【问题标题】:Asking for user input more than once in a while loop在一个while循环中多次询问用户输入
【发布时间】:2020-04-03 13:09:46
【问题描述】:

我目前正在编写一个程序,将普通文本翻译成鲸语(如果你想知道鲸语是什么,它是用 u's 和 e's 加倍的辅音撕裂的语句)

我成功编写了程序。但我希望它再次重复并经历相同的过程,直到我们手动退出它。

为此,我使用了一个 while 循环并将 exit 作为变量。但它没有像第二次那样按预期工作,它没有要求输入,而是显示提示文本并跳到退出/不退出行。 你能告诉我我的程序有什么问题吗?这是我的代码(你可以尝试自己编译执行):

#include <iostream>
#include <string>
#include <vector>

int main(){
  bool exit = false;
//Open
std::cout<<"==========\n";
std::cout<<"WHALE TALK\n";
std::cout<<"==========\n";
std::cout<<"\n";
//main loop

while (!exit){

//Variables
std::vector<char> whaletalk;
//input
std::string input;
std::cout<<"Type the text you want to translate to whale language: ";
getline(std::cin,input);
std::cout<<"\n\nWhale talk: ";

//vowels
std::vector <char> vowels = {'a','e','i','o','u'};

//sorter
//iterating through string
for (int i = 0; i < input.size(); i++){
  //iterating through vowels
  for (int j = 0; j < vowels.size(); j++){
      //case of vowels
      if(input[i] == vowels[j]){
          //case of u and e
          if ((input[i] == 'u') or (input[i] == 'e')){
              whaletalk.push_back(input[i]);
              whaletalk.push_back(input[i]);
          }
          //case of vowels other than u and e
          else {whaletalk.push_back(input[i]);}
      }
  }
}
//Output
for (int k = 0; k < whaletalk.size(); k++ ){

  std::cout<<whaletalk[k];
}
std::cout<<"\n";
// exit/no exit
std::string response;
std::cout<<'\n';
std::cout<<"Do you have more to translate?(yes/no)\n\nYour response: ";
std::cin>>response;
if (response == "NO" or response == "no" or response == "No"){
  exit = true;
}




}
}

Here is an image of the bug

【问题讨论】:

标签: c++ loops c++11 input while-loop


【解决方案1】:

当您使用&gt;&gt; 运算符读取字符串时,它只会读取下一个单词(最多一个空格字符),并将其他所有内容留在输入流中,但std::cin 仍会阻塞直到换行(输入被按下)。

std::string response;
std::cout << '\n';
std::cout << "Do you have more to translate?(yes/no)\n\nYour response: ";
std::cin >> response;
if (response == "NO" or response == "no" or response == "No") {
    exit = true;

如果您只输入一个单词,这将只在缓冲区中留下换行符(如果您确实说“ab”,那么它将留下“b\n”,response 将是“a”,而不是“ab”),所以下一个std::getline 会给你剩下的,在这种情况下是一个空行。

int main()
{
    std::string str;
    std::cout << "Enter word: ";
    std::cin >> str;
    std::cout << "Entered '" << str << "'" << std::endl;

    std::cout << "Enter line: ";
    std::getline(std::cin, str);
    std::cout << "Entered '" << str << "'" << std::endl;
}
输入单词:a
输入'a'
输入行:输入''

或者如果你有一个空格字符:

输入单词:aa bb
输入'aa'
输入行:输入'bb'

您可以在仅读取字符串响应时始终使用std::getline,以避免意外遗漏任何内容(例如“bb”)。

 std::string response;
 std::cout << '\n';
 std::cout << "Do you have more to translate?(yes/no)\n\nYour response: ";
 std::getline(std::cin, response);
 if (response == "NO" or response == "no" or response == "No") {
     exit = true;

或在任何其他&gt;&gt; 操作之后获取“剩余”内容并继续下一行。

另一种可能性是使用std::istream.ignore() 忽略剩余输入,直到最大长度和分隔符:

 std::string response;
 std::cout << '\n';
 std::cout << "Do you have more to translate?(yes/no)\n\nYour response: ";
 std::cin >> response;
 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
 if (response == "NO" or response == "no" or response == "No") {
     exit = true;

在这种情况下,std::numeric_limits&lt;std::streamsize&gt;::max() 表示任意数量,直到下一行 \n。如果用户输入说“no abc”,那么“abc”就会丢失。

【讨论】:

  • 没错,我想到了几种方法。你有没有想过其他人?
  • 不是真的 - 我打算通过一个简单的ignore() 电话发布一个更短的答案,但这远没有你的好。自从您进行编辑以来,它现在是一个近乎完美的答案! +1
  • 先生,您能解释一下当我输入“是”响应时发生了什么吗?由于我对编码不熟悉,我发现很难理解,而且我倾向于通过像“aa bb”这样的例子来更快地理解。如果您解释了我在 std::cin>>response 中输入“yes”后发生的事情,那将有很大帮助。提前谢谢!
  • 阅读您的答案几次后,我想我明白为什么我错了。这是我的假设。我使用 std::cin 来获取输入。但正如您所说,在我输入“是”之后,std::cin 从输入流中获取了“是”,但在后面留下了一行 (\n)。该行被初始输入(键入要翻译的文本)吸收,因此保持空白,然后输出保持空白,因此返回相同的问题。如果我使用 getline() 来收集输入,那么它也会吸收 line(\n) 。如果我错了,请纠正我。 (如果我是对的,也要说)。
  • 因此,在“非否”情况下执行&gt;&gt; 之后,它会循环回到getline 文本所在的顶部,从而使getline 紧跟在@987654338 之后@。 getline 将消耗换行符,因此它之后的输入是 next 行。
【解决方案2】:
  1. 您应该使用这些函数来清除输入并忽略除换行符之外的所有字符:
std::cin.clear();
std::cin.ignore(32767, '\n');

在这个函数下面:

std::cin >> ...;
  1. 这是响应的循环检查:
      while (true) {
            if (response == "NO" or response == "no" or response == "No") {
                exit = true;
                break;
            }
            else if (response == "YES" or response == "yes" or response == "Yes")
            {
                break;
            }
            else
            {
                std::cout << "\nPlease only input yes or no: ";
                std::cin >> response;
                // Clear input
                std::cin.clear();
                std::cin.ignore(32767, '\n');
            }
        }
  1. 完整代码:
#include <iostream>
#include <string>
#include <vector>

int main() {
    bool exit = false;
    //Open
    std::cout << "==========\n";
    std::cout << "WHALE TALK\n";
    std::cout << "==========\n";
    std::cout << "\n";
    //main loop

    while (!exit) {

        //Variables
        std::vector<char> whaletalk;
        std::cout << "Type the text you want to translate to whale language: ";
        //input
        std::string input;
        std::getline(std::cin, input);
        std::cout << "\n\nWhale talk: ";

        //vowels
        std::vector <char> vowels = { 'a','e','i','o','u' };

        //sorter
        //iterating through string
        for (int i = 0; i < input.size(); i++) {
            //iterating through vowels
            for (int j = 0; j < vowels.size(); j++) {
                //case of vowels
                if (input[i] == vowels[j]) {
                    //case of u and e
                    if ((input[i] == 'u') or (input[i] == 'e')) {
                        whaletalk.push_back(input[i]);
                        whaletalk.push_back(input[i]);
                    }
                    //case of vowels other than u and e
                    else { whaletalk.push_back(input[i]); }
                }
            }
        }
        //Output
        for (int k = 0; k < whaletalk.size(); k++) {

            std::cout << whaletalk[k];
        }
        std::cout << "\n";
        // exit/no exit
        std::string response;
        std::cout << '\n';
        std::cout << "Do you have more to translate?(yes/no)\n\nYour response: ";
        std::cin >> response;
        // Clear input
        std::cin.clear();
        std::cin.ignore(32767, '\n');

        while (true) {
            if (response == "NO" or response == "no" or response == "No") {
                exit = true;
                break;
            }
            else if (response == "YES" or response == "yes" or response == "Yes")
            {
                break;
            }
            else
            {
                std::cout << "\nPlease only input yes or no: ";
                std::cin >> response;
                // Clear input
                std::cin.clear();
                std::cin.ignore(32767, '\n');
            }
        }
    }
    return 0;
}

【讨论】:

  • 先生,fflush(stdin) 是做什么的?我没听说过。提前谢谢你!
猜你喜欢
  • 1970-01-01
  • 2021-02-21
  • 2021-08-13
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2013-07-05
  • 2021-11-21
  • 2013-11-16
相关资源
最近更新 更多