0Pricing
C Academy · 강의

strtok과 토큰화

문자열을 분할합니다

strtok과 토큰화은(는) CoddyKit의 무료 C Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

토큰화란 무엇인가요

토큰화란 구분 문자로 나뉜 문자열을 더 작은 조각(토큰)으로 분할하는 것입니다.

예를 들어 쉼표를 기준으로 "a,b,c"를 나누면 a, b, c 토큰을 얻습니다. C에서는 이를 위해 strtok을 제공합니다.

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

int main(void) {
    char text[] = "a,b,c";
    char *token = strtok(text, ",");
    printf("First token: %s\n", token);
    return 0;
}

strtok의 선언

char *strtok(char *str, const char *delim);

첫 번째 호출에서는 문자열을 전달합니다. 그 이후의 호출에서는 NULL을 전달하여 이전에 멈춘 위치부터 계속합니다. 다음 토큰을 반환하며, 완료되면 NULL을 반환합니다.

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

int main(void) {
    char text[] = "red green blue";
    char *tok = strtok(text, " ");
    while (tok != NULL) {
        printf("%s\n", tok);
        tok = strtok(NULL, " ");
    }
    return 0;
}

strtok은 문자열을 수정합니다

중요: strtok은 원본 문자열을 변경합니다. 각 구분자를 '\0'으로 바꾸고 같은 버퍼 안의 위치를 가리키는 포인터를 반환합니다.

따라서 읽기 전용인 문자열 리터럴 "a,b"은 토큰화할 수 없습니다.

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

int main(void) {
    char data[] = "x:y:z";
    strtok(data, ":");
    printf("data[1] is now: %d (the null byte)\n", data[1]);
    return 0;
}

쓰기 가능한 복사본 만들기

strtok은 입력을 파괴하므로, 나중에 원본이 필요하다면 먼저 문자열을 복사하세요.

지역 char 배열을 사용하거나 strcpy로 버퍼에 복사하세요.

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

int main(void) {
    const char *original = "one-two-three";
    char copy[64];
    strcpy(copy, original);
    char *tok = strtok(copy, "-");
    while (tok) {
        printf("%s\n", tok);
        tok = strtok(NULL, "-");
    }
    printf("Original intact: %s\n", original);
    return 0;
}

여러 구분자

delim 인자는 문자 집합이지 문자열이 아닙니다. 집합에 포함된 모든 문자가 구분자 역할을 합니다.

따라서 " ,;"는 공백, 쉼표, 세미콜론을 모두 구분자로 사용해 한 번에 나눕니다.

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

int main(void) {
    char text[] = "a,b;c d";
    char *tok = strtok(text, ",; ");
    while (tok) {
        printf("[%s]\n", tok);
        tok = strtok(NULL, ",; ");
    }
    return 0;
}

연속된 구분자

strtok은 연속된 구분자를 하나의 구분자로 취급하고 빈 토큰을 건너뜁니다.

따라서 "a,,b"에서는 a와 b만 얻으며, 중간의 빈 토큰은 얻지 못합니다. 빈 필드가 중요한 CSV 구문 분석에서는 이 점을 기억하세요.

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

int main(void) {
    char text[] = "a,,b";
    char *tok = strtok(text, ",");
    while (tok) {
        printf("token: %s\n", tok);
        tok = strtok(NULL, ",");
    }
    return 0;
}

토큰 개수 세기

문자열에 토큰이 몇 개 포함되어 있는지 세는 작업은 흔히 수행됩니다. 반복문 안에서 카운터를 증가시키세요.

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

int main(void) {
    char sentence[] = "the quick brown fox";
    int count = 0;
    char *tok = strtok(sentence, " ");
    while (tok) {
        count++;
        tok = strtok(NULL, " ");
    }
    printf("Word count: %d\n", count);
    return 0;
}

strtok은 숨겨진 상태를 유지합니다

strtok은 위치를 정적 내부 변수에 저장합니다. 그래서 NULL을 전달하면 이전 문자열에서 계속할 수 있습니다.

단점은 재진입할 수 없고 스레드에 안전하지 않다는 것입니다. 두 문자열을 동시에 토큰화할 수 없습니다.

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

int main(void) {
    char a[] = "1 2";
    char *t = strtok(a, " ");
    printf("%s\n", t);
    t = strtok(NULL, " ");
    printf("%s\n", t);
    return 0;
}

토큰 저장하기

분할한 뒤에도 토큰을 사용하려면 반환된 포인터를 배열에 저장하세요. 포인터는 이제 수정된 원본 버퍼 안을 가리키므로, 해당 버퍼가 계속 유지되어야 합니다.

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

int main(void) {
    char csv[] = "name,age,city";
    char *fields[10];
    int n = 0;
    char *tok = strtok(csv, ",");
    while (tok && n < 10) {
        fields[n++] = tok;
        tok = strtok(NULL, ",");
    }
    for (int i = 0; i < n; i++)
        printf("Field %d: %s\n", i, fields[i]);
    return 0;
}

재진입 가능한 대안

POSIX는 숨겨진 상태 대신 명시적인 char **saveptr을 받는 strtok_r을 제공합니다. 따라서 중첩해서 사용하거나 여러 스레드에서 사용해도 안전합니다.

이식 가능한 표준 C에서는 한 번만 순차적으로 구문 분석할 때 일반 strtok을 사용해도 괜찮습니다.

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

int main(void) {
    char text[] = "p:q:r";
    char *save;
    char *tok = strtok_r(text, ":", &save);
    while (tok) {
        printf("%s\n", tok);
        tok = strtok_r(NULL, ":", &save);
    }
    return 0;
}

실전: 경로 나누기

토큰화는 파일 경로처럼 구조화된 텍스트를 구문 분석할 때 특히 유용합니다. /를 기준으로 나누면 각 경로 구성 요소를 확인할 수 있습니다.

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

int main(void) {
    char path[] = "usr/local/bin";
    char *part = strtok(path, "/");
    while (part) {
        printf("-> %s\n", part);
        part = strtok(NULL, "/");
    }
    return 0;
}

빠른 확인

strtok의 작동 방식에 대한 이해도를 확인해 보세요.

복습

strtok으로 문자열을 나누는 방법을 배웠습니다.

  • 첫 번째 호출에는 문자열을 전달하고, 이후 호출에는 NULL을 전달합니다.
  • 입력을 수정하여 구분자를 '\0'으로 바꾸므로, 읽기 전용 문자열은 먼저 복사해야 합니다.
  • 구분자 인자는 문자 집합이며, 연속된 구분자는 하나로 합쳐집니다.
  • 정적 상태를 사용하므로 스레드에 안전하지 않습니다. 필요할 때는 strtok_r을 사용하세요.

자주 묻는 질문

“strtok과 토큰화” 강의는 무료인가요?

네 — “strtok과 토큰화” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C Academy 강의 전체를 잠금 해제할 수 있습니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“strtok과 토큰화”에서 뭘 배우나요?

문자열을 분할합니다 브라우저에서 직접 실행하는 실습 코드로 C Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“strtok과 토큰화” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. strlen, strcpy, strcat
  2. strcmp와 비교
  3. strtok과 토큰화
  4. memcpy와 memset
← C Academy(으)로 돌아가기