2010-04-12 3 views
1

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

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 У меня есть цикл при вызове функции parseInstruction бесконечно. Вывод программы «Введите следующие направления:« Когда я даю инструкции программы, он их исполняет, а затем он выводит «снова введите свои указания ниже:», и когда я снова вводю свои указания, он не выполняет их и выдает »Введите свои указания ниже: «вместо этого. Я уверен, что это очень простое решение. Я просто очень новичок в C++. Поэтому, если вы могли бы помочь мне помочь и рассказать мне, почему программа принимает только первый набор направлений. thanks

+0

С точки зрения вопроса, я думаю, у вас есть некоторые проблемы с форматированием. Убедитесь, что перед всеми строками кода есть четыре пробела. –

+0

Извините, что я попытался это исправить. – Van

+0

Спасибо за исправление моей проблемы с отступом – Van

ответ

1

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

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

+0

Я переместил ignore() после getline(), и робот не двигался, и я получил ошибку сегментации. – Van

1

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

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"; 
} 
+0

Мы используем устройства Bluetooth для отправки сигналов от и от робота (кажется, есть проблемы с задержкой). Когда робот отправляет информацию обратно на устройство, чтобы сообщить нам, что он подключен, программа помещает информацию в cin.getline() и завершает программу (которая не должна произойти теперь, когда функция находится в цикле while). Я использовал cin.ignore(), чтобы отменить это действие. Тем не менее, ваше предложение, безусловно, стоит того, и я попробую его, когда вернусь в лабораторию завтра около 5 вечера EST. – Van

+0

Это хорошее предложение; когда ваша программа, кажется, неправильно интерпретирует ввод, первое, что нужно проверить, это то, что программа видит вход так, как вы думаете, что это должно быть! –

+0

Вы были правы, cin.ignore() выбрасывает первую букву ввода. Без cin.ignore() программа не будет запускаться так, чтобы я закончил работу, переместив ее в мою программу-драйвер сразу после того, как он подключился к роботу и как раз перед вызовом функции ручного диска. – Van

0

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

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; 
    } 
} 
+0

Мне нравится использовать кожух переключателя намного лучше, чем если бы высказывания почему-то, поэтому я, вероятно, сделаю снимок. Должен ли я определять письмо каждого случая? EX: char w [] = "forward"; – Van

+0

Я думаю, вы неправильно поняли, как работает коммутатор. Параметр переключателя сравнивается с каждым случаем, поэтому вам не нужно объявлять какие-либо переменные для каждого случая. – datdo

+0

Ничего, я просто понял, какой переключатель (токен [3]) по какой-то причине. Он находит четвертую букву, и если ее w (3-я буква вперед), то она выполняет случай 'w'.Извините, что я крупный n00b, это определенно будет немного, пока я не помогу на этом сайте. – Van

Смежные вопросы