Почему мой цикл while принимает новый ввод (c ++) - PullRequest
1 голос
/ 13 апреля 2010

Я написал программу для получения входных данных от пользователя, их разбора на токены и перемещения робота в соответствии с входными данными. Моя проблема заключается в попытке выполнить более одной команды. Код выглядит так:

void Navigator::manualDrive()
{

    const int bufSize = 42;
    char uinput[bufSize];
    char delim[] = " ";
    char *token;
    while(true)
    {

        Navigator::parseInstruction(uinput);
    }
}  
/* parseInstruction(char *c) -- parses cstring instructions received
* and moves robot accordingly
*/


void Navigator::parseInstruction(char * c)
{

    const int bufSize = 42;
    char uinput[bufSize];
    char delim[] = " ";
    char *token;


    cout << "Enter your directions below: \n";
    cin.ignore();
     cin.getline (uinput, bufSize);


    token=strtok(uinput, delim);
    if(strcmp("forward", token) == 0)
    {
        int inches;
        token = strtok(NULL, delim);
        inches = atoi (token);
        Navigator::travel(inches);
    }
    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*/);
    }
    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.0041 * degrees - 0.0523);
            myRobot.turnLeft(1/*speed*/, value/*time*/);
        }
    }
    if(strcmp("turn",token) == 0)
    {
        int degrees;
        token = strtok(NULL, delim);
        if(strcmp("right",token) == 0)
        {
            token = strtok(uinput, delim);
            degrees = atoi (token);
            double value = fabs(0.0041 * degrees - 0.0523);
            myRobot.turnRight(1/*speed*/, value/*time*/);
        }
    }
    if(strcmp("stop",token) == 0)
    {
        myRobot.motors(0,0);
    }
}

В функции manualDrive у меня есть цикл while, бесконечно вызывающий функцию parseInstruction. Программа выводит «Введите ваши указания ниже:« Когда я даю инструкции программе, она их выполняет, а затем выводит », введите ваши указания ниже:« Снова, и когда я снова ввожу мои указания, она не выполняет их и выводит ». Введите ваши указания ниже: «вместо. Я уверен, что это очень простое исправление. Я просто новичок в c ++. Так что, если вы могли бы помочь мне и скажите мне, почему программа принимает только первый набор указаний. спасибо

Ответы [ 3 ]

1 голос
/ 13 апреля 2010

Вам не нужна строка cin.ignore() здесь. cin.getline должен уже извлечь и отбросить разделитель. Я подозреваю, что это выбрасывало первого персонажа вашей команды. Вы можете проверить это, изменив свои операторы if на else-ifs и добавив в конце блок else:

if(strcmp("forward", token) == 0)
else if(strcmp("back",token) == 0)
else if(strcmp("turn",token) == 0)
else if(strcmp("turn",token) == 0)
else if(strcmp("stop",token) == 0)
else
{
    std::cerr << "Unknown command '" << token << "'\n";
}
1 голос
/ 13 апреля 2010

Это звучит как распространенная проблема, возникающая, когда ваша команда cin читает символ новой строки из предыдущего ввода. Я вижу, что у вас есть cin.ignore (), которая обычно решает эту проблему, но она все равно происходит.

Попробуйте переместить игнорирование после команды getline ()

0 голосов
/ 13 апреля 2010

Я полагаю, что ваши множественные операторы if являются частью причины наряду с неправильным чтением команд. Я бы также использовал endl вместо символа / n. Это означает, что вам не нужно игнорировать.

void Navigator::manualDrive()
{

    const int bufSize = 42;
    char uinput[bufSize];
    char delim[] = " ";
    char *token;
    while(true)
    {

        Navigator::parseInstruction(uinput);
    }
}  
/* parseInstruction(char *c) -- parses cstring instructions received
* and moves robot accordingly
*/


void Navigator::parseInstruction(char * c)
{

    const int bufSize = 42;
    char uinput[bufSize];
    char delim[] = " ";
    char *token;


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


    token=strtok(uinput, delim);
    switch(token[3])//the command's fourth letter
    //needed letter because strings don't work with switch
    {
        case 'w': //forward
            int inches;
            token = strtok(NULL, delim);
            inches = atoi (token);
            Navigator::travel(inches);
            break;//this signifies the end of the case

        case 'k': //back
            int inches;
            token = strtok(NULL, delim);
            inches = atoi (token);
            double value = fabs(0.0735 * fabs(inches) - 0.0550);
            myRobot.backward(1/*speed*/, value/*time*/);
            break;

        case 'n': //turn
            int degrees;
            token = strtok(NULL, delim);
            if(strcmp("left",token) == 0)
            {
                token = strtok(uinput, delim);
                degrees = atoi (token);
                double value = fabs(0.0041 * degrees - 0.0523);
                myRobot.turnLeft(1/*speed*/, value/*time*/);
            }
            else if(strcmp("right",token) == 0)
            {
                token = strtok(uinput, delim);
                degrees = atoi (token);
                double value = fabs(0.0041 * degrees - 0.0523);
                myRobot.turnRight(1/*speed*/, value/*time*/);
            }
            break;

        case 'p': //stop
            myRobot.motors(0,0);
            break;

        default: //the default case
            cout << "Command Unknown" << endl;
            break;
    }
}
...