2017-01-12 8 views
1

제목이 혼란 스럽다는 것을 깨닫고 그것을 명확하게 생각할 수 없습니다. 기본적으로 strtok 루프 내에서 strtok 루프를 호출하지만, 내부 strtok 함수가 runCommand에서 반환 될 때 첫 번째 strtok 루프가 중지됩니다. 첫 번째 세미콜론 다음에 다른 인수가있는 경우에도 루프를 종료합니다. runCommand()를 호출하지 않으면 예상대로 작동하고 세미콜론으로 구분 된 모든 명령을 구문 분석합니다.strtok strtok이 원래 토큰의 사본으로 작동하지 않음 - C

이 코드의 목적은 세미콜론으로 구분 된 명령 줄을 구문 분석 한 다음 명령과 명령 인수를 구문 분석하여 나중에 execvp를 입력하는 것입니다. 이것은 내가 문제가되는 유일한 부분입니다. 여기에 있습니다 :

void parseCommand(char *userLine) 
{ 
    if(strchr(userLine, ';')) 
    { 
    // Get first token 
    token = strtok(userLine, ";"); 
    // Loop through all tokens 
    while(token != NULL) 
    { 
     // Make a copy 
     char *copy = malloc(strlen(token) + 1); 
     strcpy(copy, token); 
     runCommand(copy); 
     free(copy); 
     printf("process returned!\n"); 
     token = strtok(NULL, ";"); 
    } 
    } 
} 
void runCommand(char *token) 
{ 
    char *args[20]; 
    char **command = args; 
    //Tokenize each command based on space 

    char *temp = strtok(token, " \n"); 
    while (temp != NULL) 
    { 
    *command++ = temp; 
    temp = strtok(NULL, " \n"); 
    } 
    *command = NULL; 
// code for fork and execvp here 
} 

누군가가 내 첫 번째 함수의 구문 분석을 왜 망쳐 놓고 있는지 설명 할 수 있습니까? 나는 왜 그것이 나의 원래 토큰의 복사본으로 작동하지 않는지 이해하지 못합니다. 아마 간단하지만 너무 오랫동안 봤어?

+3

"strtok 루프 내에서 strtok 루프를 호출하려고합니다."- 그렇게 할 수 없습니다. 'strtok'의 디자인이 짜증 난다. – user2357112

+0

네,'strtok'을 "재귀 적으로"사용할 수는 없습니다. 새로운,'NULL '이 아닌 인수를 전달하자마자 이전 인수에 대해서는 완전히 잊어 버립니다. 토큰은 먼저 깊이가 아닌 우선적으로 처리해야합니다. –

+0

[Tokenization :'strtok()','strtok_r()'및'strtok_s()'] 문서보기 (http://stackoverflow.com/documentation/c/1990/strings/2557/tokenisation-strtok-strtok- r-and-strtok-s # t = 20170113015701136593). –

답변

5

기능 strtok은 재 입력 불가입니다. 현재 상태를 기억합니다. 따라서 segfault가 없으면 반복 호출에 NULL을 전달합니다.

호출자가 상태를 저장할 수 있도록 strtok_s 또는 strtok_r (구현에 따라 다름)을 사용하는 것을 고려하십시오. 이들은 중첩 된 방식으로 사용될 수 있습니다.

+0

'strtok_r'은 표준이 아니므로'strtok_s'를 사용하는 것이 좋습니다. – Olaf

+0

감사합니다! 다음 번에는 문서를 자세히 살펴볼 것입니다. – Tee

+0

@Olaf : Windows에서 작업하는 경우 strtok_s()가 사용 가능하므로 사용할 수 있습니다. 유닉스에서 작업한다면'strtok_s()'를 사용할 수 없다 - POSIX는 Annex K의 함수를 거부했다 ([TR24731의 안전한 함수를 사용 하는가?] (http://stackoverflow.com/questions/372980/do- 24731-safe-functions)을 사용하고 있으며 본질적으로 어떤 유닉스 시스템도 그것들을 구현하지는 않는다. 그러나'strtok_r()'이 가능하다. 다행히도이 둘은 기능적으로 동일합니다. 플랫폼이 명확하지 않으면'strtok_s()'또는'strtok_r()'이 분명히 오해의 소지가 있습니다. –

3

strtok은 실행되는 컨텍스트에 대해 알지 못하지만 다소 전역 적으로 작동합니다.

strtok_r을 사용해보십시오. 여러 개의 개별 용도가 서로 방해하지 않도록 문맥을 지정할 수 있습니다. man page에서

:

다른 문자열이 동시에 다른 saveptr 인수를 지정 strtok_r() 호출 시퀀스를 사용하여 분석 할 수있다.