为什么我的令牌返回NULL并且如何修复它?(c ++)

时间:2010-04-14 00:50:51

标签: c++ null token strtok

我创建了一个程序,用于从用户获取字符串输入并将其解析为标记并根据输入移动机器人。该程序应该识别这些输入(其中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
停止

我也遗漏了对我的程序的一个重要限制我不允许使用标准库中的字符串

2 个答案:

答案 0 :(得分:2)

代码行:

token=strtok(uinput, delim);
如果token为空或仅包含uinput字符串中的字符,

会将delim设置为NULL。

更改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()的正常回报,您的代码需要准备好处理它。

答案 1 :(得分:0)

尝试在调试器下运行,并在收到错误时查看uinput的值。

同时检查堆栈回溯:当您收到错误时,输入是来自manualDrive还是autoDrive?