2010-04-14 2 views
1

사용자로부터 문자열 입력을 가져 와서 토큰으로 구문 분석하고 입력에 따라 로봇을 이동시키는 프로그램을 만들었습니다. 프로그램은 이러한 입력 (x는 정수)을 인식하기로되어 있습니다 : "앞으로 x" "뒤로 x" "왼쪽으로 돌기 x" "오른쪽으로 돌림 x"및 "정지". 프로그램은 "중지"를 제외한 모든 명령에 대해 수행 할 작업을 수행합니다. 내가 "stop"을 입력하면 프로그램은 "whats happening?"을 출력합니다. 왜 내 토큰이 NULL을 반환하고 어떻게 해결할 수 있습니까? (C++)

if(token == NULL) 
{ 
    cout << "whats happening?" << endl; 
} 

왜 토큰 가져 오기 NULL이, 나는이 그래서 읽을 해결할 수있는 방법을 제대로 "중지"않습니다

: 나는 상태 라인을 작성했기 때문에? 내가 다음으로 호출 된 함수가 autoDrive이다이 때문에 내 드라이버 프로그램에서 while 루프의 탈옥과 manualDrive을 종료 할 필요가

bool stopper = 0; 
void Navigator::manualDrive() 
{ 
    VideoStream video(&myRobot, 0);//allows user to see what robot sees 
    video.startStream(); 
    const int bufSize = 42; 
    char uinput[bufSize]; 
    char delim[] = " "; 
    char *token; 

    while(stopper == 0) 
    { 
    cout << "Enter your directions below: " << endl; 
    cin.getline(uinput,bufSize); 
    Navigator::parseInstruction(uinput); 
    } 
} 
/* parseInstruction(char *c) -- parses cstring instructions received 
* and moves robot accordingly 
*/ 


void Navigator::parseInstruction(char * uinput) 
{ 

    char delim[] = " "; 
    char *token; 


// cout << "Enter your directions below: " << endl; 
// cin.getline (uinput, bufSize); 

    token=strtok(uinput, delim); 
    if(token == NULL) 
    { 
     cout << "whats happening?" << endl; 
    } 
    if(strcmp("forward", token) == 0) 
    { 
     int inches; 
     token = strtok(NULL, delim); 
     inches = atoi (token); 
     double value = fabs(0.0735 * fabs(inches) - 0.0550); 
     myRobot.forward(1, value); 
    } 
    else if(strcmp("back",token) == 0) 
    { 
     int inches; 
     token = strtok(NULL, delim); 
     inches = atoi (token); 
     double value = fabs(0.0735 * fabs(inches) - 0.0550); 
     myRobot.backward(1/*speed*/, value/*time*/); 
    } 
    else if(strcmp("turn",token) == 0) 
    { 
     int degrees; 
     token = strtok(NULL, delim); 
     if(strcmp("left",token) == 0) 
     { 
      token = strtok(uinput, delim); 
      degrees = atoi (token); 
      double value = fabs(0.00467 * degrees - 0.04); 
      myRobot.turnLeft(1/*speed*/, value/*time*/); 
     } 


     else if(strcmp("right",token) == 0) 
     { 
      token = strtok(uinput, delim); 
      degrees = atoi (token); 
      double value = fabs(0.00467 * degrees - 0.04); 
      myRobot.turnRight(1/*speed*/, value/*time*/); 
     } 
    } 
    else if(strcmp("stop",token) == 0) 
    { 
     stopper = 1; 
    } 
    else 
    { 
     std::cerr << "Unknown command '" << token << "'\n"; 
    } 
} 
/* autoDrive() -- reads in file from ifstream, parses 
* and moves robot according to instructions in file 
*/ 
void Navigator::autoDrive(string filename) 
{ 
    const int bufSize = 42; 
    char fLine[bufSize]; 
    ifstream infile; 
    infile.open("autodrive.txt", fstream::in); 

    while (!infile.eof()) 
    { 
     infile.getline(fLine, bufSize); 
     Navigator::parseInstruction(fLine); 
    } 

    infile.close(); 
} 

: 여기
는 코드입니다.
autodrive.txt 파일과 같이 보인다 : 앞으로

2
우회전 30
다시 3
차례 50
정지

이 또한 내가 '내 프로그램에 중요한 제한을 왼쪽으로 왼쪽으로 표준 라이브러리의 문자열을 사용할 수 없습니다.

+0

잘못된 동작을 제공하는 autodrive.txt에있는 샘플을 게시하십시오. –

+0

"whats happening?"을 인쇄 한 직후에 프로그램 segfaults를 예상합니다. strcmp에 NULL을 전달했기 때문에? 그렇지 않다면 어딘가에 프로그램의 다른 줄을 찾아 "what 's happening?"이라고 인쇄하십시오. "autodrive"모드로 전환 할 수 있으며 파일의 어딘가에 빈 줄이 있습니까? –

+0

모호함을 드려 죄송합니다. 아니, autoDrive에 가지 않는다. zsh : segmentation fault (코어 덤프 됨) ./driver " autoDrive를 별도로 실행했는데"중지 "라는 텍스트의 마지막 줄에 세그먼테이션 오류가 발생합니다. 다음과 함께 내 게시물을 편집 할 것입니다. 텍스트 파일의 예입니다. – Van

답변

0

디버거에서 실행하고 uinput의 값을 g 그 오류.

또한 그 시점에서 스택 추적을 확인하십시오. 오류가 발생하면 입력이 manualDrive 또는 autoDrive에서 오는 것입니까?

2

코드의 라인 : uinput이 비어 있거나에만 delim 문자열에있는 문자로 구성되어있는 경우

token=strtok(uinput, delim); 

NULL로 token을 설정합니다.

당신의 NULL 체크 주위에 약간의 코드를 변경하면 당신은 무슨 일이 일어나고 있는지 알아내는 데 도움이 될 수 있습니다 어떤 경우

std::string original_uinput(uinput); // save input string for debugging 

token=strtok(uinput, delim); 
if(token == NULL) 
{ 
    cout << "whats happening? uinput was: " << original_uinput << endl; 
} 

, NULLstrtok()에서 정상 복귀이며, 당신의 코드를 처리 할 수 ​​있도록 준비해야 .

+2

'std :: string'을 사용할 수 없다는 편집에 대한 의견으로 :'std :: string'을 픽스로 사용하는 것을 제안하지 않았습니다. 당신은'strtok()'로부터'NULL' 리턴을 얻고 있을지 모릅니다. 'cin'이나'autodrive.txt'에서 비어있는 (또는 모든 공백) 줄을 처리하는 방법은 당신에게 달린 것입니다 - 여러분은 단순히 돌아와서 다른 줄을 얻을 수도 있고, 'stop' 명령이 발행되었습니다. 그 점은'strtok()'의'NULL' 리턴이 적절히 처리 될 필요가 있다는 것입니다. –