'strtok static variable'에 해당되는 글 1건

  1. 2014.05.29 strtok에 NULL을 전달하는 이유
프로그래밍/C2014. 5. 29. 09:32

strtok를 쓸 때, 왜 두번째 콜에서 NULL을 넘겨줄까? 그냥 그러려다 찾아보았다.


char str[] = "Hello World. How are you?";
        char delim[] = " ";
        char *ptr;

ptr = strtok(str, delim);
        printf("%s\n", ptr);
        while(ptr = strtok(NULL, delim))
            printf("%s\n", ptr);


다음은 strtok.c 의 내용이다.(glibc 2.19버전)


18 #include <string.h>
19 
20 
21 static char *olds;
22 
23 #undef strtok
24 
25 /* Parse S into tokens separated by characters in DELIM.
26  If S is NULL, the last string strtok() was called with is
27  used. For example:
28  char s[] = "-abc-=-def";
29  x = strtok(s, "-"); // x = "abc"
30  x = strtok(NULL, "-="); // x = "def"
31  x = strtok(NULL, "="); // x = NULL
32  // s = "abc\0=-def\0"
33 */
34 char *
36  char *s;
37  const char *delim;
38 {
39  char *token;
40 
41  if (s == NULL)
42  s = olds;
43 
44  /* Scan leading delimiters. */
45  s += strspn (s, delim);
46  if (*s == '\0')
47  {
48  olds = s;
49  return NULL;
50  }
51 
52  /* Find the end of the token. */
53  token = s;
54  s = strpbrk (token, delim);
55  if (s == NULL)
56  /* This token finishes the string. */
57  olds = __rawmemchr (token, '\0');
58  else
59  {
60  /* Terminate the token and make OLDS point past it. */
61  *s = '\0';
62  olds = s + 1;
63  }
64  return token;
65 }


41라인을 보면 NULL일 경우, static 변수 old로 대체한다. 아! 그래서 NULL을 써서 이어서 파싱이 되게 하는구나.  그리고 static변수라... 쓰레드 사용시에 문제가 있을 거 같다.

추가로 찾아본 내용을 보니,(http://ogoons.tistory.com/m/post/70) 다음과 같은 주의사항이 있다.


1. strtok()의 사용 후, 원본 문자열의 데이터를 보장할 수 없다.
2. visual studio 상위 버전에 문제가 있을 수 있다.
3. strtok()은 내부적으로 문자열 분리를 위해 static변수를 놓고 정적공유를 함으로 , thread-safe하지 않다.(음 역시)


따라서 위의 상황들을 개선한 strtok_s()를 쓰길 권장한다고 한다.


char str[] = "Hello World Good, Morning Sunshine";

char delim[] = " ,";

char *ptr;

char *context = NULL;

ptr = strtok_s(str, delim, &context);

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

while(ptr = strtok_s(NULL, delim, &context))

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


Posted by code cat