在 cin 之后使用 getline(cin, s) [英] Using getline(cin, s) after cin

查看:46
本文介绍了在 cin 之后使用 getline(cin, s)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要以下程序来获取用户输入的整行并将其放入字符串名称中:

I need the following program to take the entire line of user input and put it into string names:

cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;

getline(cin, names);

使用 cin >>然而,getline() 命令之前的 number 命令(我猜这是问题所在),它不允许我输入名称.为什么?

With the cin >> number command before the getline() command however (which I'm guessing is the issue), it won't allow me to input names. Why?

我听说过一些关于 cin.clear() 命令的消息,但我不知道它是如何工作的,也不知道为什么这样做是必要的.

I heard something about a cin.clear() command, but I have no idea how this works or why this is even necessary.

推荐答案

cout << "Enter the number: ";
int number;
if (cin >> number)
{
    // throw away the rest of the line 
    char c;
    while (cin.get(c) && c != '
')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found
";
            exit(EXIT_FAILURE);
        }
    cout << "Enter names: ";
    string name;
    // keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
    while (getline(cin, name))
        ...use name...
}
else
{
    std::cerr << "ERROR reading number
";
    exit(EXIT_FAILURE);
}

在上面的代码中,这个位...

In the code above, this bit...

    char c;
    while (cin.get(c) && c != '
')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found
";
            exit(EXIT_FAILURE);
        }

...在数字只包含空格之后检查输入行的其余部分.

...checks the rest of the input line after the number contains only whitespace.

那太冗长了,所以在 >>> 之后的流上使用 ignorex 是一种经常推荐的替代方法,可以将内容丢弃到下一个换行符,但它冒着丢弃非空白内容的风险,这样做会忽略文件中的损坏数据.您可能关心也可能不关心,具体取决于文件内容是否可信、避免处理损坏数据的重要性等.

That's pretty verbose, so using ignore on the stream after >> x is an oft-recommended alternative way to discard content through to the next newline, but it risks throwing away non-whitespace content and in doing so, overlooking corrupt data in the file. You may or may not care, depending on whether the file's content's trusted, how important it is to avoid processing corrupt data etc..

因此,std::cin.clear()(和 std::cin.ignore())对此不是必需的,但对于删除错误状态.例如,如果您想给用户很多机会输入有效数字.

So, std::cin.clear() (and std::cin.ignore()) isn't necessary for this, but is useful for removing error state. For example, if you want to give the user many chances to enter a valid number.

int x;
while (std::cout << "Enter a number: " &&
       !(std::cin >> x))
{
    if (std::cin.eof())
    {
        std::cerr << "ERROR unexpected EOF
";
        exit(EXIT_FAILURE);
    }

    std::cin.clear();  // clear bad/fail/eof flags

    // have to ignore non-numeric character that caused cin >> x to
    // fail or there's no chance of it working next time; for "cin" it's
    // common to remove the entire suspect line and re-prompt the user for
    // input.
    std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}

使用skipws 或类似的方法不能更简单吗?

ignore 的另一个简单但半生不熟的替代方案是使用 std::skipws 在阅读行之前跳过任意数量的空格...>

Can't it be simpler with skipws or similar?

Another simple but half-baked alternative to ignore for your original requirement is using std::skipws to skip any amount of whitespace before reading lines...

if (std::cin >> number >> std::skipws)
{
    while (getline(std::cin, name))
        ...

...但是如果它得到像1E6"这样的输入(例如,一些科学家试图输入 1,000,000,但 C++ 仅支持浮点数的表示法)不会接受,您最终会将 number 设置为 1E6 读取为 name 的第一个值.另外,如果您有一个有效数字后跟一个或多个空行,这些行将被默默忽略.

...but if it gets input like "1E6" (e.g. some scientist trying to input 1,000,000 but C++ only supports that notation for floating point numbers) won't accept that, you'd end up with number set to 1, and E6 read as the first value of name. Separately, if you had a valid number followed by one or more blank lines, those lines would be silently ignored.

这篇关于在 cin 之后使用 getline(cin, s)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆