2010-12-28 3 views
7

나는 csv 문자열을 구문 분석하기 위해 c에서 strtok()을 사용하고 있습니다. 먼저 정확한 크기의 문자열을 할당 할 수 있도록 토큰의 수를 알아 내기 위해 토큰 화합니다. 마지막으로 토큰 화에 사용했던 것과 동일한 변수를 사용합니다. 매번 두 번째로 그래도 그래도 strtok(NULL, ",")은 더 많은 토큰이 파싱 되어도 NULL을 반환합니다. 누군가 내가 잘못하고있는 것을 말해 줄 수 있습니까?문자열을 두 번 토큰 화하여 strtok()로

char* tok; 
int count = 0; 
tok = strtok(buffer, ","); 
while(tok != NULL) { 
    count++; 
    tok = strtok(NULL, ","); 
} 

//allocate array 

tok = strtok(buffer, ","); 
while(tok != NULL) { 
    //do other stuff 
    tok = strtok(NULL, ","); 
} 

그래서 두 번째 while 루프에서는 더 많은 토큰이 있더라도 첫 번째 토큰이 발견 된 후에 항상 종료됩니다. 아무도 내가 뭘 잘못하고 있는지 알아?

+2

요즘 누구나 'strtok()'가 무엇인지 아는 사람들은 분명하지만 누구도 설명서를 읽지 못했습니까? 아무도 내가 C를 배울 때 그것에 대해 말하지 않았지만, 내가 그것에 대해 알게 되 자마자 그것에 대해 읽었습니다. –

답변

16

strtok()은 작동하는 문자열을 수정하여 구분 기호 문자를 null로 바꿉니다. 따라서 두 번 이상 사용하려면 복사본을 만들어야합니다.

+4

+1 : 그렇기 때문에'strtok()'을 사용하는 것이 종종 좋은 생각이 아닐 때가 있습니다 ... –

+0

당신이 이깁니다. +1 빠른 답변. – Septagram

2

사본을 만들 필요가 없습니다. strtok()은 토큰 화 문자열을 수정하지만 대개의 경우 토큰을 다시 처리하려는 경우 문자열이 이미 토큰 화되었음을 의미합니다.

여기 프로그램이 첫 번째 패스 토큰을 처리하기 위해 약간의 수정이다 : 이것은 내가 처음 게시보다 불행하게도 까다 것을

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

int main() 
{ 
    int i; 
    char buffer[] = "some, string with , tokens"; 

    char* tok; 
    int count = 0; 
    tok = strtok(buffer, ","); 
    while(tok != NULL) { 
     count++; 
     tok = strtok(NULL, ","); 
    } 


    // walk through the tokenized buffer again 
    tok = buffer; 

    for (i = 0; i < count; ++i) { 
     printf("token %d: \"%s\"\n", i+1, tok); 
     tok += strlen(tok) + 1; // get the next token by skipping past the '\0' 
     tok += strspn(tok, ","); // then skipping any starting delimiters 
    } 

    return 0; 
    } 

주 - strspn()에 대한 호출은 '\ 건너 뛰는 이후에 수행 될 필요가 strtok()에 의해 배치 된 0을 반환합니다 (strtok()). 반환하는 토큰에 대한 선행 구분 기호 문자는 건너 뜁니다 (소스의 구분 문자를 바꾸지 않음).

+0

또 다른 방법은 배열의 첫 번째 패스에서 토큰 포인터를 저장하는 것입니다. 물론, 최대 개수의 토큰 또는 동적 배열을 갖는 것을 의미합니다. 하지만 그것도 효과가 있습니다. –

1

strsep를 사용하십시오. 실제로 포인터를 업데이트합니다. 귀하의 경우에는 문자열의 주소를 전달하는 대신 NULL을 호출해야합니다. strsep의 유일한 문제점은 이전에 힙에 할당되어 있고 포인터를 처음으로 유지 한 다음 나중에 해제하는 경우입니다.

char * strsep (char ** string, char * delim);

char * string; char * token; 토큰 = strsep (& 문자열, ",");

strtok는 C 코스의 일반적인 소개에 사용됩니다. strsep를 사용하면 훨씬 좋습니다. :-) 혼란스러워하지 말아라. "오, 젠장 .- 아직 NULL을 통과시켜야 해. 내 입장을 망쳐 놨어."

관련 문제