【问题标题】:How to get rid of bad input one word at a time instead of one line at a time?如何摆脱一次一个单词而不是一次一行的错误输入?
【发布时间】:2015-02-20 14:39:17
【问题描述】:

我正在阅读《C++ 入门加/Stephen Prata》

这是本书的代码

    while (!(cin >> golf[i])) {
        cin.clear();    // reset input
        while (cin.get() != '\n')
            continue;   // get rid of bad input
        cout << "Please enter a number: ";
    }

上面的代码很容易理解。

但这本书的上下文提到了

"...程序在while循环中使用cin.get()从行尾读取剩余的输入。这消除了错误的输入,以及行中的任何其他内容。 另一种方法是读取下一个空格,这样可以一次删除一个单词而不是一次一行。 最后,程序告诉用户输入一个数字。”

我想知道另一种方法是什么?

我尝试用不同的方式表达代码,但我知道这是不正确的。

    while (!(cin >> golf[i])) {
        cin.clear();    // resset input
        char word[20];
        while (cin >> word)
            continue;   // get rid of bad input
        cout << "Please enter a number: ";
    }

我如何编写代码以读取下一个空格,从而消除一次一个单词而不是一次一行的错误输入?

感谢您的阅读。

【问题讨论】:

  • 您可能需要编辑问题的标题,以便在没有引用上下文的情况下有意义。
  • 您可能还想看看The Definitive C++ Book Guide and List,它避免了推荐这本书(查看代码示例,我明白为什么!),链接到一个不利的评论。它建议了其他几本可能更受欢迎的初学者书籍。
  • 谢谢。新标题好吗?

标签: c++


【解决方案1】:

让我们从查看现有代码开始:

    while (cin.get() != '\n')
        continue;

这是读到换行符的内容。我们读取一个字符,将其与换行符进行比较,如果不相等,我们读取另一个字符。因此,它读取字符,并在到达换行符时停止读取。

如果我们想读取一个空格字符,我们只需更改我们比较的值:

    while (cin.get() != ' ')
        continue;

如果我们想在 any 空白处停止阅读,我们可以使用一个函数来告诉我们一个字符是否为空白。该函数看起来像这样:

bool is_white_space(char ch) { 
    return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v';
}

但这是一个足够常见的任务,标准库已经有一个isspace 函数,所以我们不必自己编写。我们只需要使用它:

while (!isspace(cin.get())
    continue;

就我个人而言,我至少会考虑将它单独放入一个函数中,并给它一个可读的名称,如skip_to_whitespace,这样我们的外循环看起来像:

void skip_to_space(std::istream &in) { 
    in.clear();
    while (!isspace(in.get()))
        continue;
}

// ...
while (!(cin >> golf[i])) {
    skip_to_space(cin);
    cout << "Please enter a number: ";
}

至少对我来说,这似乎使代码的意图更加明显——我们不必通读循环的内容来弄清楚它应该做什么——这从名称中很明显函数。

不过,我还有最后一件事要改变。如果条件为假,while 循环通常应该无效。然而,这个总是从它的输入中读取至少一个字符,不管那个字符可能是什么。为了使这一事实更加明显,我更喜欢使用do 循环,以正确反映循环始终至少执行一次的意图:

void skip_to_space(std::istream &in) { 
    in.clear();
    char ch;

    do {
        ch = in.get();
    } while (!isspace(ch));
}

现在很明显,cin.get() 总是至少发生一次,并且会继续发生,直到我们到达一个空白字符为止。

【讨论】:

    【解决方案2】:

    要抛出单词直到达到一个数字,请执行以下操作:

    string word;
    
    cout << "Please enter a number: ";
    
    while(!(cin >> golf[i])){
        cin.clear();
        cin >> word;
    
        if(cin.rdbuf()->in_avail() == 1){
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cout << "Please enter a number: ";
        }
    }
    

    删除整行的一种方法是使用ignore

    while (!(cin >> golf[i])) {
        cin.clear();    // resset input
        cin.ignore(numeric_limits<streamsize>::max(), '\n');   // get rid of bad input
        cout << "Please enter a number: ";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多