본문 바로가기

TroubleShooting/Etc

strtok() 대신 strsep() 를 사용하자.

728x90

문자열 파싱 용도로 간단하게 사용하는 함수인 strtok() 는 구분자 사이가 비어있을 경우 문제가 발생할 경우가 있다.


#include <stdio.h>

#include <string.h>


main()

{

    char *sep = "\f";

    char *tok = NULL;

    char buf[128];

    char *string, *tofree;


    //sprintf(buf, "1%c2%c3%c4%c5",  '\f', '\f', '\f', '\f');

    sprintf(buf, "1%c%c3%c4%c5",  '\f', '\f', '\f', '\f');


    tok = strtok(buf, sep);

    printf("tok1(%s)\n", tok);


    tok = strtok(NULL, sep);

    printf("tok2(%s)\n", tok);


    tok = strtok(NULL, sep);

    printf("tok3(%s)\n", tok);


    tok = strtok(NULL, sep);

    printf("tok4(%s)\n", tok);


    tok = strtok(NULL, sep);

    printf("tok5(%s)\n", tok);

}

 첫번째 buf 의 결과는 정상적으로 1, 2, 3, 4, 5 가 나오지만, "2" 을 없앤 두번째 buf 의 결과는 다음과 같이 하나씩 앞으로 밀리게 된다.

$ ./a

tok1(1)

tok2(3)

tok3(4)

tok4(5)

tok5((null))


 strsep() 함수를 사용해서 다음과 같이 변경해보면

#include <stdio.h>

#include <string.h>


main()

{

    char *sep = "\f";

    char *tok = NULL;

    char buf[128];

    char *string, *tofree;


    //sprintf(buf, "1%c2%c3%c4%c5",  '\f', '\f', '\f', '\f');

    sprintf(buf, "1%c%c3%c4%c5",  '\f', '\f', '\f', '\f');


    tofree = string = strdup(buf);

    while ((tok = strsep(&string, sep)) != NULL)

        printf("%s\n", tok);


    free(tofree);

}

  의도한 대로 두번째는 NULL 이고 나머지는 정상적으로 나온다.

$ ./b

1


3

4

5