1

ユーザーから文字列入力を取得し、それをトークンに解析し、入力に従ってロボットを動かすプログラムを作成しました。プログラムは、次の入力 (x は整数) を認識することになっています: 「前方 x」、「後方 x」、「左折 x」、「右折 x」、および「停止」。プログラムは、「停止」を除くすべてのコマンドに対して想定されていることを実行します。「停止」と入力すると、プログラムは「どうしたの?」と出力します。私は次のような行を書いたからです:

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

トークンが NULL になるのはなぜですか? また、これを修正して「停止」を適切に読み取るにはどうすればよいですか?
コードは次のとおりです。

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();
}

while ループから抜け出して manualDrive を終了するには、これが必要です。私のドライバー プログラムでは、次に呼び出される関数が autoDrive であるためです。
autodrive.txt ファイルは次のようになります。

前進 2
右折 30
後退 3
左折 50
停止

また、プログラムの重要な制限を省略しました。標準ライブラリの文字列を使用することは許可されていません

4

2 に答える 2

2

コードの行:

token=strtok(uinput, delim);

空の場合、または文字列内の文字のみで構成されtokenている場合は、NULLに設定されます。uinputdelim

チェックの周りのコードを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;
}

いずれにせよ、NULLはからの通常の戻りでstrtok()あり、コードはそれを処理する準備をする必要があります。

于 2010-04-14T01:21:07.027 に答える
0

デバッガーで実行してみて、エラーが発生したときの uinput の値を確認してください。

また、その時点でスタック トレースバックを確認してください。エラーが発生した場合、入力は manualDrive または autoDrive から来ていますか?

于 2010-04-14T00:59:42.390 に答える