C언어에서 문자열 공백 제거: 간단한 방법과 응용

C언어에서 문자열의 공백 제거는 데이터 전처리와 문자열 조작에서 필수적인 작업입니다. 공백이 포함된 문자열은 데이터 비교, 검색, 변환 과정에서 문제를 일으킬 수 있습니다. 본 기사에서는 기본적인 반복문 활용 방법부터 고급 라이브러리와 정규표현식까지 다양한 공백 제거 방법을 구체적인 코드 예제와 함께 다룹니다. 이로써 효율적이고 간단하게 공백 제거를 구현할 수 있는 실질적인 팁을 제공합니다.

목차

공백 제거의 기본 개념


문자열에서 공백 제거는 데이터를 깔끔하게 정리하고 처리하기 위해 자주 필요한 작업입니다. 공백은 데이터 비교나 검색 과정에서 의도치 않은 오류를 일으킬 수 있기 때문에, 이를 적절히 처리하는 것이 중요합니다.

문자열에서 공백의 역할


공백은 문자열을 구분하거나 가독성을 높이는 데 유용하지만, 다음과 같은 문제를 유발할 수 있습니다.

  • 데이터 비교 시 일치하지 않는 결과 발생
  • 불필요한 공백으로 데이터 처리 속도 저하
  • 입력값 유효성 검사 오류

공백 제거의 기본 원리


공백 제거의 핵심은 문자열 내 공백 문자를 식별하고 제거하여 새 문자열을 생성하는 것입니다.

  • 순회 방식: 문자열의 각 문자를 확인하여 공백이 아닌 문자를 새로운 위치로 이동
  • 문자열 분리 방식: 문자열을 공백 기준으로 분리한 뒤 재조합

이러한 방법을 활용하면 문자열을 효율적으로 정리하고 처리할 수 있습니다.

반복문을 활용한 공백 제거


반복문은 공백 제거를 구현하는 가장 기본적이고 직관적인 방법입니다. for문 또는 while문을 사용해 문자열을 순회하며 공백을 필터링합니다.

기본 알고리즘

  1. 원본 문자열을 한 글자씩 순회합니다.
  2. 공백이 아닌 문자를 새로운 문자열에 추가합니다.
  3. 순회가 끝나면 공백이 제거된 새 문자열이 완성됩니다.

코드 예제

#include <stdio.h>
#include <string.h>

void removeSpaces(char* source) {
    int i, j = 0;
    int len = strlen(source);
    char result[len + 1]; // 공백 제거된 문자열 저장

    for (i = 0; source[i] != '\0'; i++) {
        if (source[i] != ' ') { // 공백이 아니면
            result[j++] = source[i];
        }
    }
    result[j] = '\0'; // 문자열 종료
    strcpy(source, result); // 원본 문자열에 결과 복사
}

int main() {
    char str[] = "C programming   is fun!";
    printf("Original: '%s'\n", str);

    removeSpaces(str);
    printf("Without spaces: '%s'\n", str);

    return 0;
}

코드 설명

  1. removeSpaces 함수는 문자열을 순회하며 공백이 아닌 문자를 새로운 배열에 저장합니다.
  2. 순회가 끝난 후 결과를 원본 문자열에 복사합니다.
  3. main 함수에서 테스트 문자열의 공백을 제거하여 결과를 출력합니다.

장점과 단점

  • 장점: 간단하고 가볍게 구현 가능
  • 단점: 문자열을 순회하며 새 배열을 생성하므로 메모리 사용량 증가

반복문을 활용한 공백 제거는 간단한 작업에 적합하며, 초보자에게도 이해하기 쉬운 방법입니다.

strtok() 함수의 활용


C언어의 표준 라이브러리 함수인 strtok()를 사용하면 문자열을 공백을 기준으로 분리하고 재조합하여 공백을 제거할 수 있습니다. 이 방법은 간단하면서도 효율적으로 문자열 처리를 가능하게 합니다.

strtok() 함수 개요


strtok() 함수는 문자열을 특정 구분자로 나누는 데 사용됩니다. 구분자를 공백으로 설정하면 공백을 기준으로 문자열을 나눌 수 있습니다.

함수 선언:

char *strtok(char *str, const char *delim);
  • str: 나눌 대상 문자열
  • delim: 구분자로 사용할 문자 집합

코드 예제

#include <stdio.h>
#include <string.h>

void removeSpaces(char* source) {
    char* token;
    char result[100] = ""; // 공백 제거된 문자열 저장
    const char delim[2] = " "; // 공백 구분자

    // 첫 번째 토큰 가져오기
    token = strtok(source, delim);

    while (token != NULL) {
        strcat(result, token); // 결과 문자열에 추가
        token = strtok(NULL, delim); // 다음 토큰 가져오기
    }

    strcpy(source, result); // 원본 문자열에 결과 복사
}

int main() {
    char str[] = "C programming   is fun!";
    printf("Original: '%s'\n", str);

    removeSpaces(str);
    printf("Without spaces: '%s'\n", str);

    return 0;
}

코드 설명

  1. strtok 함수로 문자열을 공백 기준으로 나누어 각 토큰을 순차적으로 가져옵니다.
  2. 각 토큰을 결과 문자열에 추가하여 공백 없이 재조합합니다.
  3. 결과를 원본 문자열에 복사하여 공백 제거 작업을 완료합니다.

장점과 단점

  • 장점: 구현이 간단하며 라이브러리 함수로 처리 속도가 빠릅니다.
  • 단점: 원본 문자열이 변경되며, 다중 스레드 환경에서는 사용하기 부적합합니다.

strtok()를 활용한 공백 제거는 문자열을 재구성하는 데 효과적이며, 간단한 구현을 통해 빠르게 결과를 얻을 수 있는 방법입니다.

정규표현식과 외부 라이브러리 사용


정규표현식과 외부 라이브러리를 사용하면 문자열 공백 제거를 더욱 효율적이고 유연하게 처리할 수 있습니다. 이 방법은 대규모 데이터 처리나 복잡한 문자열 패턴 처리에 적합합니다.

정규표현식 활용의 이점


정규표현식은 특정 패턴을 탐지하고 대체하는 데 강력한 도구로, 문자열 내 모든 공백(연속 공백 포함)을 한 번에 처리할 수 있습니다.

PCRE 라이브러리를 활용한 예제


PCRE(Perl Compatible Regular Expressions) 라이브러리는 C언어에서 정규표현식을 사용할 수 있도록 지원합니다.

예제 코드

#include <stdio.h>
#include <string.h>
#include <pcre.h>

void removeSpacesWithRegex(char* source) {
    const char* pattern = "\\s+"; // 모든 공백(스페이스, 탭 등)
    const char* error;
    int erroffset, ovector[30];
    pcre* re;

    re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
    if (!re) {
        printf("Regex compilation failed at offset %d: %s\n", erroffset, error);
        return;
    }

    int rc = pcre_exec(re, NULL, source, strlen(source), 0, 0, ovector, 30);
    if (rc >= 0) {
        char result[100] = "";
        int last_pos = 0;
        for (int i = 0; i < rc; i++) {
            int start = ovector[2 * i];
            int end = ovector[2 * i + 1];
            strncat(result, source + last_pos, start - last_pos);
            last_pos = end;
        }
        strcat(result, source + last_pos);
        strcpy(source, result);
    }
    pcre_free(re);
}

int main() {
    char str[] = "C    programming   is   fun!";
    printf("Original: '%s'\n", str);

    removeSpacesWithRegex(str);
    printf("Without spaces: '%s'\n", str);

    return 0;
}

코드 설명

  1. 정규표현식 정의: \\s+ 패턴은 하나 이상의 공백(스페이스, 탭 등)을 탐지합니다.
  2. PCRE 컴파일: 정규표현식을 컴파일하여 실행 가능한 객체를 생성합니다.
  3. 공백 제거: 탐지된 공백 부분을 제외하고 문자열을 재구성합니다.
  4. 결과 출력: 공백이 제거된 문자열을 원본에 복사합니다.

장점과 단점

  • 장점: 복잡한 문자열 패턴 처리 가능, 연속 공백 및 다양한 공백 문자 한 번에 처리
  • 단점: PCRE와 같은 외부 라이브러리 설치 및 링크 필요, 초기 설정 복잡

정규표현식과 외부 라이브러리는 공백 제거뿐만 아니라 고급 문자열 조작에도 유용하며, 대규모 프로젝트에서 강력한 도구로 활용될 수 있습니다.

응용 예제: 파일 입출력에서의 공백 제거


파일 입출력 작업에서는 데이터를 읽어오고, 처리한 뒤 다시 저장하는 과정이 자주 필요합니다. 이 과정에서 공백 제거는 데이터 정리와 전처리 단계의 중요한 작업입니다. 아래 예제에서는 파일의 내용을 읽어와 공백을 제거하고, 결과를 새로운 파일에 저장하는 방법을 다룹니다.

코드 예제

#include <stdio.h>
#include <string.h>

void removeSpaces(char* source) {
    int i, j = 0;
    int len = strlen(source);
    char result[len + 1]; // 공백 제거된 문자열 저장

    for (i = 0; source[i] != '\0'; i++) {
        if (source[i] != ' ') { // 공백이 아니면
            result[j++] = source[i];
        }
    }
    result[j] = '\0'; // 문자열 종료
    strcpy(source, result); // 원본 문자열에 결과 복사
}

int main() {
    FILE *inputFile, *outputFile;
    char buffer[256];

    // 입력 파일 열기
    inputFile = fopen("input.txt", "r");
    if (inputFile == NULL) {
        printf("Error: Could not open input file.\n");
        return 1;
    }

    // 출력 파일 열기
    outputFile = fopen("output.txt", "w");
    if (outputFile == NULL) {
        printf("Error: Could not open output file.\n");
        fclose(inputFile);
        return 1;
    }

    // 파일 읽기, 공백 제거, 쓰기
    while (fgets(buffer, sizeof(buffer), inputFile)) {
        removeSpaces(buffer); // 공백 제거
        fprintf(outputFile, "%s", buffer); // 결과 쓰기
    }

    // 파일 닫기
    fclose(inputFile);
    fclose(outputFile);

    printf("File processed successfully. Check 'output.txt'.\n");
    return 0;
}

코드 설명

  1. 파일 열기: fopen()을 사용해 입력 파일과 출력 파일을 엽니다.
  2. 버퍼 읽기: fgets()로 파일에서 한 줄씩 데이터를 읽습니다.
  3. 공백 제거: removeSpaces 함수를 호출하여 읽어온 문자열의 공백을 제거합니다.
  4. 결과 쓰기: fprintf()를 사용해 공백이 제거된 데이터를 출력 파일에 저장합니다.
  5. 파일 닫기: 모든 파일을 닫아 메모리 누수를 방지합니다.

응용 가능성

  • 데이터 정리: 로그 파일, 데이터 파일 등에서 불필요한 공백을 제거하여 처리 용이성 증가
  • 포맷 통일: 데이터 형식 표준화
  • 효율성 향상: 데이터 비교 및 검색 속도 개선

파일 입출력과 공백 제거를 결합한 이 예제는 실무에서 자주 활용되며, 텍스트 데이터의 품질을 높이는 데 매우 유용합니다.

요약


C언어에서 문자열의 공백 제거는 데이터를 정리하고 처리하기 위한 필수 기술입니다. 본 기사에서는 반복문, strtok() 함수, 정규표현식 및 외부 라이브러리 활용 방법을 다루었으며, 파일 입출력과의 응용 예제도 제시했습니다. 이러한 다양한 접근법을 통해 문자열 공백 제거 문제를 효율적으로 해결할 수 있습니다.

목차