【问题标题】:C++ getline is not empty when no input is entered未输入任何输入时,C++ getline 不为空
【发布时间】:2018-04-21 10:01:29
【问题描述】:

我是 C++ 新手,但我仍在努力思考输入/输出流的工作原理。

我目前正在尝试编写一个函数来确保用户输入一个 int,并告诉他们输入是空的还是无效的 int。

我正在使用 getline 并尝试使用 cin.clear 和 cin.ignore 但我似乎无法让它工作并且不知道我哪里出错了。

如果我输入一个字母,它会起作用,但是如果我只是在没有输入的情况下按 Enter,它不会说没有检测到输入。

void testStuff()
{
    string number;

    ws(cin);//skips Whitespaces

    if (getline(cin, number) && number.end() !=
        find_if_not(number.begin(), number.end(), &isdigit))
    {
        if (number.empty())
        {
            cout << "No input detected" << endl;
            testStuff();
        }
        cout << "Please input a Valid number" << endl;
        testStuff();
    }
}

【问题讨论】:

  • 如果字符串为空,find_if_not 唯一可以返回的是number.end()number.end() == number.end() 并且正文未输入。
  • 假设您的ws 按规定工作,您应该无法输入空输入。如果您只是按下enter 键,它将被读取为一个换行符,它被归类为空格(即isspace('\n') == true)。要调用getline,您必须输入非空格的内容,因此您使用getline 读取的内容不能为空。
  • @JerryCoffin 是的,但是 ws 出现在 getline 调用之前
  • @user4581301 我明白你在说什么,我应该先检查它是否为空
  • @MichaelGrinnell:准确地说——所以为了继续调用getline,用户必须输入一些非空白的内容。调用 getline 时,该非空白字符必须在输入缓冲区中,因此它读取的内容不可能为空。

标签: c++ cin getline istream


【解决方案1】:

假设您的ws 按规定工作(跳过输入中的空格),当您调用getline 时,必须输入除空格以外的其他内容。因此,当getline 被调用时,非空白字符必须在输入缓冲区中等待,并且getline 必须返回一个非空字符序列(即,从第一个非空白字符到下一个新行)。

例如,让我们编写自己的 ws 来显示它正在跳过的字符:

void ws(std::istream &is) {
    while (std::isspace(is.peek())) {
        char ch;
        is.get(ch);
        std::cout << "Read: " << (int)ch << '\n';
    }
}

现在,当我们调用testStuff() 并按enter 时,我们得到Read: 10 作为我们的输出——即ws 已读取并跳过我们输入的换行符。

因此,要调用getline,用户必须输入除空格以外的其他内容,并且换行符是空格。所以,但是在调用 getline 的时候,我们知道输入缓冲区中有一些非空白字符在等待,所以当调用 getline 时,它必须产生一个非空结果.

【讨论】:

  • 好吧,是的,我花了一分钟时间来解决这个问题。基本上摆脱ws,先检查输入是否为空,然后检查它是否为数字。谢谢:)
【解决方案2】:

我假设我不知道实现的每个函数都正确编写。然后,我有这样的代码(简化):

#include <iostream>
#include <string>
using namespace std;

int main() {
    string number;
    if (getline(cin, number))
    {
        if (number.empty())
        {
            cout << "No input detected" << endl;
            main();
        }
        cout << "Please input a Valid number" << endl;
        main();
    }
}

我不知道find_if_not(number.begin(), number.end(), &amp;isdigit) 的实现,所以我跳过了它。我已将源代码放在 Ideone.com 上,您可以查看它HERE。在通过“just enter”后,程序运行正常。这意味着,您没有向我们展示的功能实现之一工作不正确。为了帮助您,我们需要完整的源代码(如果没有,只需要部分)。此外,您应该跳过“使用命名空间 std;”。我认为,number.end() != find_if_not(number.begin(), number.end(), &amp;isdigit)) 实施不正确。您应该考虑一下有人在 cmets 中告诉您的内容 - “如果字符串为空,则 find_if_not 唯一可以返回的是 number.end()。number.end() == number.end() 并且不输入正文。”

【讨论】:

  • 从程序中调用main 是不好的。
  • 当然是,但这是一个快速而肮脏的例子。我不想仅仅为了让它“有效”而制作 60 行程序,而这样的程序表现得应该如此。我认为 OP 不会使用我的代码...
  • @KrzysztofSzewczyk find_if_not 获取第一个和最后一个位置,并将迭代器返回到特定条件的第一次出现。所以 isdigit 是条件,所以如果它返回最后一个元素,则意味着没有整数
猜你喜欢
  • 2016-01-24
  • 1970-01-01
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多