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

查看:215
本文介绍了在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()命令之前的命令(命令,但我猜这是问题),它不会允许我输入名称。为什么?

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 != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            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\n";
    exit(EXIT_FAILURE);
}

在上面的代码中,此位...

In the code above, this bit...

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

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

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

这很冗长,所以使用 ignore >> x 是一种推荐的替代方法,通过到下一个换行符丢弃内容,但它可能会丢弃非空格内容,这样做,可以忽略文件中的损坏数据。您可能会也可能不在乎,这取决于文件的内容是否值得信赖,避免处理损坏的数据的重要性等。

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()(and std :: cin.igore())对于这不是必需的,但对于删除错误状态很有用。例如,如果您想给用户很多机会输入有效的数字。

So, std::cin.clear() (and std::cin.igore()) 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\n";
        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或类似工具不能更简单吗?



忽略的另一个简单但半暂时的替代方法是使用 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 设置为 1 E6 读为 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天全站免登陆