[출처 : http://sp0ngee.tistory.com/51]


어느날 strtok() 함수의 메뉴얼 페이지를 보게 되었는데 다음과 같은 내용이 있었습니다.

버그
이 함수를 사용해서는 안된다. 만일 사용해야 한다면, 다음을 주의하라:
이 함수는 처음 인자를 수정한다.
구분자의 원본은 잃게 된다.
이 함수는 상수 문자열에서는 사용해서는 안된다.
strtok() 함수는 파싱하는 동안 정적 버퍼를 사용한다. 그래서 thread safe가 아니다. 만일 이것이 문제라면 strtok_r() 를 사용해라.

여기서 말하는 thread safe란 것은 여러 thread가 동시에 사용되어도 안전하단 말입니다.
thread safe에 대해서 더 자세히 알고 싶으시면 출처의 링크를 참고하시거나, 구글에서 검색해 보세요.
[ 'thread safe' 출처: http://kldp.org/node/36904 ]

그래서 앞으로 문자열 파싱을 할 일이 생기거든 strtok_r() 함수를 사용해 보려고 합니다.
머리가 좋지 못한 저는 여기에 정리해 놓고, 필요할 때 가져다 쓸려구요...-_ㅜ
혹시 필요하신 분들도 가져다가 사용하시길 바랍니다.

또한, 코드 내용 중에 잘못된 부분이나, 수정하면 더~ 좋은 프로그램이 되겠다라는 곳이 있으면 주저하지 마시고 답변 달아주세요! 다른 분들이 잘못된 정보를 알아가면 안되니까요. ^^

사용 예제를 보기 전에 간단하게 메뉴얼 페이지 내용을 적어봤습니다.

이름
strtok, strtok_r - 문자열에서 토큰들을 뽑아낸다.

사용법
#include <string.h>
char *strtok(char *s, const char *delim);
char *strtok_r(char *s, const char *delim, char **ptrptr);

설명
`토큰`이란 문자열 delim에 속하지 않는 문자들로 이루어진 비어 있지 않은 문자열이며 \0 이나 delim에 있는 문자가 뒤따른다.

strtok() 함수는 문자열 s를 토큰으로 파싱하기 위해 사용된다. strtok()의 첫번째 인자로 s를 주면, 가장 앞에 있는 토큰을 구하고, 그 문자열안의 다음 토큰을 구하고자 할 때에는 첫번째 인자를 NULL로 설정하여야 한다. 각 호출은 다음 토큰에 대한 포인터를 반환하거나 더이상  토큰이  발견되지  않는다면 NULL을 반환한다. 토큰이 구분자로 끝난다면, 이 구분자는 \0 로 겹쳐 쓰여지며 다음 문자에 대한 포인터가 strtok()에 대한 다음 호출을 위해 저장된다. 구분 문자열 delim는 각 호출 시 다를 수 있다.

strtok_r() 함수는 strtok() 와 동일하게 작동한다. 그러나 정적 버퍼를 사용하는 대신에 이 함수는 char * 포인터로 할당된 유저에 대한 포인터를 사용한다. 이 포인터, ptrptr 파라미터는 같은 문자열을 파싱하는 동안 같아야만 한다.

다음은 예제 소스코드 입니다.
01.#include <stdio.h>
02.#include <string.h>
03.#define DELIM "_"
04. 
05.int main(void)
06.{
07.char buf[] = "My_name_is_ubuntu";
08.char tmp[4][10] = {};
09.char *token;
10.char *ptr[2];
11.int i = 0;
12. 
13.token = strtok_r(buf, DELIM, &ptr[0]);
14.while( token )
15.{
16.strcpy(tmp[i], token);
17.token = strtok_r(tmp[i], DELIM, &ptr[1]);
18.while( token )
19.{
20.strcpy(tmp[i], token);
21.token = strtok_r(NULL, DELIM, &ptr[1]);
22.}
23.token = strtok_r(NULL, DELIM, &ptr[0]);
24.i++;
25.}
26. 
27.for(i=0; i<4; i++)
28.printf("tmp[%d]: %s\n", i, tmp[i]);
29. 
30.return 0;
31.}

실행 결과 입니다.




*참고로 delim은 delimiter의 약자입니다. 단어의 뜻은 '구분 문자'입니다.
이 단어는 자기 테이프 등에서 데이터의 시작(끝)을 나타내는 문자나 기호를 말합니다.

+ Recent posts