2010-03-27 3 views
3

char * str을 첫 번째 매개 변수 (구분 기호 문자열이 아님)로 사용하면 strtok가 올바르게 작동하지 않습니다.strtok accept : char * str

해당 표기법으로 문자열을 할당하는 영역과 관련이 있습니까? (내가 아는 한, 읽기 전용 영역이다). 사전에

감사

예 :

//char* str ="- This, a sample string."; // <---doesn't work 
char str[] ="- This, a sample string."; // <---works 
char delims[] = " "; 
char * pch; 
printf ("Splitting string \"%s\" into tokens:\n",str); 
pch = strtok (str,delims); 
while (pch != NULL) 
{ 
    printf ("%s\n",pch); 
    pch = strtok (NULL, delims); 
} 
return 0; 

답변

6

첫 번째 경우에는 문자열 리터럴을 strtok()에 전달합니다. strtok()는이 문자열을 수정하고 문자열 리터럴을 법적으로 수정할 수 없으므로 정의되지 않은 동작이 발생합니다. 두 번째 경우 컴파일러는 문자열을 배열에 복사합니다. 배열 내용을 수정할 수 있으므로이 코드는 정상입니다.

+0

나는 본다. 그 기능의 행동을 알지 못했습니다. 감사합니다. – bks

2

strtok이 첫번째 인수를 수정합니다.

귀하의 경우 1 strtok에 대한 인수는 수정할 수없는 문자열 literal이므로 strtok이 실패합니다. 그러나 경우 2에서 인수는 수정 가능 char 배열이며 strtok은 더 작은 문자열로 수정됩니다.

+0

나는 본다. 음, 너와 다른 남자는 매우 도움이되었다. 고마워. – bks

0

여기 코드는 모든 부분을 표기해야합니다.

  • 점점 문자 포인터

이 내게 줄 안에 그 사촌 할 때 스레드

  • 무료 결과에서는 StrDup을 할 strtok_r을 사용
  • malloc을 사용 strtok_r에 문자 포인터를 사용하기위한에서는 StrDup를 사용
  • 나는 아무것도 잊었을 때의 힌트

    #include <string.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    
    #define WHITE " \t\n" // white space, tab and newline for tokenizing arguments 
    #define MAXARGC 50 // max number of arguments in buf 
    
    void handlecommand(int argc, char *argv[]) 
    { 
        // do some handle code, in this example, just print the arguments 
        for(int i = 0; i < argc; i++) 
         printf("argv[%d]='%s'\n", i, argv[i]); 
    } 
    
    void parsecommand(char * cmdstr) 
    { 
        char *cmdstrdup = strdup(cmdstr); 
        if(cmdstrdup == NULL) 
         //insuficient memory, do some errorhandling. 
         return; 
        char *saveptr; 
        char *ptr; 
        char *argv[MAXARGC]; 
        int argc; 
    
        if((ptr = strtok_r(cmdstrdup, WHITE, &saveptr)) == NULL) 
        { 
         printf("%s\n", "no args given"); 
         return; 
        } 
    
        argv[argc = 0] = cmdstrdup; 
        while(ptr != NULL) { 
         ptr = strtok_r(NULL, WHITE, &saveptr); 
         if(++argc >= MAXARGC-1) // -1 for room for NULL at the end 
          break; 
         argv[argc] = ptr; 
        } 
    
        // handle command before free 
        handlecommand(argc, argv); 
    
        // free cmdstrdup, cuz strdup does malloc inside 
        free(cmdstrdup); 
    } 
    
    int main(int argc, char const *argv[]) 
    { 
        parsecommand("command arg1 arg2 arg3\targ4\narg5 arg6 arg7"); 
        return 0; 
    } 
    

    결과

    argv[0]='command' 
    argv[1]='arg1' 
    argv[2]='arg2' 
    argv[3]='arg3' 
    argv[4]='arg4' 
    argv[5]='arg5' 
    argv[6]='arg6' 
    argv[7]='arg7' 
    
  • +2

    답변에 불필요한 이야기가 많으며, 배낭, 프로그래밍을 시작할 때 등등. 최소화하려고 시도 할 수도 있습니다. 철자 및 대문자 사용도 가능합니다. 나는 당신이 읽고있는 책을 좋아한다는 것을 알고있다. 그러나 헤더 파일을 사용하면 코드 샘플을 그대로 실행하기가 어렵고, 표준 포함을 선호 할 수도있다. 그리고 마지막으로 5 년된 질문에 답을한다면 코드를 테스트하지 않았다는 말은 아닙니다. 5 년을 기다렸습니다. 시험을 위해 조금 더 기다릴 수 있습니다. 평론가를위한 –

    +0

    thx. 쓸모없는 이야기를 제거하고, 프로그램을 테스트 해 필요한 헤더를 추가했습니다. – had