40 문자열 자르기

지금까지 문자열을 복사하거나 붙이는 방법을 알아보았습니다. 이번에는 주어진 문자열을 자르는 방법을 알아보겠습니다. 참고로 문자열 자르기는 포인터를 이용하는 방식이라 내용이 어려울 수 있습니다.

40.1 문자를 기준으로 문자열 자르기

먼저 특정 문자를 기준으로 문자열을 자르는 방법입니다. 문자열을 자르는 함수는 strtok 이며 함수 이름은 문자열을 조각(token)으로 나누다(string tokenize)에서 따왔습니다(string.h 헤더 파일에 선언되어 있습니다).

  • strtok(대상문자열, 기준문자);
    • char *strtok(char *_String, char const *_Delimiter);
    • 자른 문자열을 반환, 더 이상 자를 문자열이 없으면 NULL을 반환

다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.

string_tokenize_array.c

#define _CRT_SECURE_NO_WARNINGS    // strtok 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>    // strtok 함수가 선언된 헤더 파일

int main()
{
    char s1[30] = "The Little Prince";  // 크기가 30인 char형 배열을 선언하고 문자열 할당

    char *ptr = strtok(s1, " ");      // " " 공백 문자를 기준으로 문자열을 자름, 포인터 반환

    while (ptr != NULL)               // 자른 문자열이 나오지 않을 때까지 반복
    {
        printf("%s\n", ptr);          // 자른 문자열 출력
        ptr = strtok(NULL, " ");      // 다음 문자열을 잘라서 포인터를 반환
    }

    return 0;
}

실행 결과

The
Little
Prince

strtok 함수는 지정된 문자를 기준으로 문자열을 자릅니다. 즉, strtok(s1, " ");와 같이 " " (공백 문자)를 넣어주면 공백으로 구분하여 문자열을 자릅니다(단, 기준 문자를 ' '로 묶으면 안 됩니다). 특히 strtok 함수는 잘린 문자열을 한 번에 얻을 수 없어서 while 반복문으로 문자열을 계속 자르다가 문자열이 나오지 않으면 반복문을 끝내는 방식으로 사용합니다.

char *ptr = strtok(s1, " ");      // " " 공백 문자를 기준으로 문자열을 자름, 포인터 반환

while (ptr != NULL)               // 자른 문자열이 나오지 않을 때까지 반복
{
    printf("%s\n", ptr);          // 자른 문자열 출력
    ptr = strtok(NULL, " ");      // 다음 문자열을 잘라서 포인터를 반환
}

여기서 while 반복문 안의 strtok 함수는 ptr = strtok(NULL, " ");처럼 자를 문자열 부분에 NULL을 넣어줍니다. 자세히 설명하자면 NULL을 넣었을 때는 직전 strtok 함수에서 처리했던 문자열에서 잘린 문자열만큼 다음 문자로 이동한 뒤 다음 문자열을 자릅니다. 만약 ptr = strtok(ptr, " ");처럼 잘린 문자열의 포인터를 다시 넣었을 때는 다음 문자로 이동하지 못하고 처음에 나오는 문자열만 계속 자르게 됩니다. 즉, 다음과 같은 결과가 나옵니다.

The
The
The
The
...

strtok 함수를 사용할 때는 처음에만 자를 문자열를 넣어주고, 그다음부터는 NULL을 넣어준다는 점을 기억하세요.

다음은 strtok 함수의 동작 순서입니다. 먼저 처음 호출되는 strtok" " (공백 문자)를 찾아서 NULL로 채운 뒤 문자열의 첫 부분인 "The"를 자릅니다.

그림 40‑1 strtok 함수로 문자열 자르기 1

이제 while 반복문 안의 strtokNULL을 넣어주어 앞에서 잘린 문자열만큼 다음 문자로 이동합니다. 그리고 다시 공백 문자를 찾아서 NULL로 채운 뒤 "Little"을 자릅니다. 하지만 아직 문자열 끝에 있는 NULL을 만나지 못했으므로 계속 반복합니다.

그림 40‑2 strtok 함수로 문자열 자르기 2

다시 strtokNULL을 넣어주어 앞에서 잘린 문자열만큼 다음 문자로 이동합니다. 이번에는 공백 문자가 아닌 문자열 마지막의 NULL을 만났으므로 NULL을 그대로 두고 "Prince"를 반환합니다.

그림 40‑3 strtok 함수로 문자열 자르기 3

직전 strtok에서 공백 문자(" ")를 만나지 못했으므로 더 이상 자를 문자열이 없습니다. 따라서 NULL을 반환하고 while 반복문을 끝냅니다.

그림 40‑4 strtok 함수로 문자열 자르기 4

strtok 함수는 문자열을 새로 생성해서 반환하는 것이 아니라 자르는 부분을 널 문자(NULL)로 채운 뒤 잘린 문자열의 포인터를 반환합니다. 따라서 원본 문자열의 내용을 바꾸므로 사용에 주의해야 합니다.