2016-11-19 4 views
0

Я пытаюсь проверить вход для вопроса quit/return в своей программе, поэтому пользователь вынужден ввести либо 'r', либо 'q'.Проверка ввода переменной char

Мне удалось заставить его почти работать. Проблема в том, что пользователь вводит 'r' или 'q' в начале, за которым следуют случайные буквы, тогда программа принимает этот ввод. Любые идеи о том, как получить программу, чтобы разрешить только один 'r' или 'q'?

void exit() 
{ 
    char choice; 
    bool badInput; 

    do 
    { 
     cout << "Press 'r' to return to the menu\nPress 'q' to quit the program\n\n" << endl; 
     cin >> choice; 

     badInput = cin.fail(); 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    } while (badInput == true && choice == 'r' && choice == 'q' && (cin.peek() == EOF)); 


     if (choice == 'q') 
     { 
      system("CLS"); 
      cout << "Bye!\n"; 
      system("PAUSE"); 
     } 
     else if (choice == 'r') 
     { 
      system("CLS"); 
      main(); 
     } 
     else 
     { 
      exit(); 
     } 
} 
+0

Использовать 'std :: getl ine() ', чтобы прочитать всю строку ввода. Вот для чего это. –

+0

Тестирование против'true', как правило, бессмысленно, вот что логическое условие внутри' if' уже делает. 'while (badInput && ...' должно быть достаточно. – tadman

+0

Вместо того, чтобы явно требовать, чтобы они вводили только 'r' или' q', было бы проще взять первую букву того, что они ввели, а затем игнорировать все после нее. , 'do ... while (choice == 'r')' цикл, скорее всего, лучше подходит для вашей цели, чем вызов 'main()' снова или определение функции с именем 'exit()' в глобальном пространстве имен. \ [Примечание что стандарт C++ говорит [вам не разрешено вызывать 'main()' из самой программы) (http://eel.is/c++draft/basic.start.main#3), в отличие от некоторых других Языки. \] –

ответ

0

У вас очень странный способ приблизиться к этой проблеме, и у вас много проблем. В частности, создание функции с именем exit() проблематично, так как это основная функция и вызов ее рекурсивно, чтобы попытаться получить вход, также не является хорошим планом. У вас уже есть цикл, вам просто нужно использовать его более эффективно.

Аналогично, main() вызывается автоматически, и у вас никогда не должно быть причин для его вызова вручную.

Вот первый переписывают проход:

void getInput() 
{ 
    char choice; 

    while (true) 
    { 
     cout << "Press 'r' to return to the menu\nPress 'q' to quit the program\n\n" << endl; 

     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

     cin >> choice; 

     switch (choice) 
     { 
      case 'q': 
       system("CLS"); 
       cout << "Bye!\n"; 
       system("PAUSE"); 
       exit(0); 
       break; 
      case 'r': 
       system("CLS"); 
       doMain(); 
       break; 
     } 
    } 
} 

Это, очевидно, нужно больше работать, но, по крайней мере, должна теоретически функции. В вашем исходном коде вы требуете, чтобы входное значение было одновременно двумя разными вещами, что невозможно, этот код никогда не будет работать.

Я также рекомендую вам прекратить делать такие вещи, как system("CLS") и system("PAUSE"), и вместо этого сделать что-то в C++ изначально. Это не переносимый код, и он ужасно неуклюжим, поскольку это зависит от команд с DOS 1980-х годов.

+0

Это действительно переписывается таким образом, что имеет больше смысла, однако он делает то же самое, что и мой код. Я имею в виду, что он принимает строку, пока «r» или «q» первое, что мне нужно. У меня есть процедура выхода, потому что я создаю программу калькулятора для своего задания, чего я хотел вызвать exit(); в конце каждой другой функции вместо создания этого кода в каждой функции имеет смысл? Могу ли я спросить, что вы подразумеваете под «что-то в C++ изначально» ?, я только начал программировать в сентябре, поэтому извините за это – PinkieBarto

+0

'exit()' - это стандартная функция C, от которой также зависит C++, поэтому избегайте конфликтов с этим. 'main()' еще более особенный. Если вы переписываете 'exit()' это как удаление двери в комнате, вам придется выпрыгнуть из окна, так что не делайте этого. Вызов 'system (...)' выполняет команду, внешнюю по отношению к C++. Выполнение чего-то C++ изначально означает использование стандартной библиотеки для получения того же эффекта. Обычно писать [такой код как анти-шаблон] (http://stackoverflow.com/questions/24776262/pause-console-in-c-program), который лучше всего избегать. – tadman

+0

У вас может быть некоторая дальнейшая работа, чтобы сделать здесь, я не могу выполнить ваше задание для вас, но это должно быть основанием для работы от этого, по крайней мере, правдоподобного. – tadman

0

Обработка входа используйте

Большинство реализации забуференный cin, так что вход будет возвращен только после того, как пользователь нажимает кнопку ввода. Если это неприемлемо для вас, вам придется использовать функции, зависящие от ОС.

Если это нормально для вас, то если вы прочитаете символ, будет передан только первый из них: оставшиеся символы до тех пор, пока ввод не будет ждать последующих чтений. Поэтому, вместо того, чтобы читать один символ, я предлагаю вам прочитать полную строку в строку:

void want_exit() 
{ 
    const string message="Press 'r' to return to the menu\nPress 'q' to quit the program\n"; 
    string line; 

    cout << message << endl; 
    while (getline(cin, line) && line.length()!=1 
      && tolower(line[0])!='y' && tolower(line[0])!='n') 
    { 
     cout << "Invalid input" <<endl << message <<endl; 
     line.resize(0); 
    } 

Теперь строка содержит либо один действительный символ, или пустой (в случае преждевременного ВФ, а это означает, что было перенаправление ввода и что в любом случае не будет больше ввода).

Обработка ввода

Вы не можете называть рекурсивно main(): вместо этого вы должны вернуться из функции, а также организовать вызывающую функцию так, чтобы продолжить процесс

if (line.empty() || tolower(line[0])!='y') { 
     system("CLS"); // This is non portable 
     cout << "Bye!\nPress enter..."; 
     cin.getch(); // as good as system("PAUSE"); 
     std::exit(0); // be aware of the naming issue ! 
    } 
    return; 
} 

Функция вызова (main()?) Затем использовал бы его в петле:

while (...) { 
    ... 
    if (...) 
     want_exit();  
} 
Смежные вопросы