首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在cin之后使用getline(cin,s)

在cin之后使用getline(cin,s)
EN

Stack Overflow用户
提问于 2011-04-21 13:29:22
回答 13查看 84.8K关注 0票数 48

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

代码语言:javascript
复制
cout << "Enter the number: ";
int number;
cin >> number;

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

getline(cin, names);

但是,在getline()命令之前使用cin >> number命令(我猜这就是问题所在),它不允许我输入姓名。为什么?

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

EN

回答 13

Stack Overflow用户

回答已采纳

发布于 2011-04-21 13:50:35

代码语言:javascript
复制
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);
}

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

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

...checks输入行中数字后面的其余部分只包含空格。

为什么不直接使用ignore呢?

这非常冗长,所以在>> x之后对流使用ignore是一种经常推荐的替代方法,可以将内容丢弃到下一个换行符,但这样做可能会丢弃非空格内容,并在这样做时忽略文件中损坏的数据。您可能关心,也可能不关心,这取决于文件的内容是否可信,避免处理损坏数据的重要性等。

那么你什么时候会使用clear和ignore呢?

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

代码语言:javascript
复制
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或类似的东西就不能简单点吗?

对于您的原始需求,ignore的另一个简单但不成熟的替代方案是使用std::skipws在读取行之前跳过任意数量的空格...

代码语言:javascript
复制
if (std::cin >> number >> std::skipws)
{
    while (getline(std::cin, name))
        ...

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

票数 11
EN

Stack Overflow用户

发布于 2012-07-09 03:11:47

代码语言:javascript
复制
cout << "Enter the number: ";
int number;
cin >> number;

cin.ignore(256, '\n'); // remaining input characters up to the next newline character
                       // are ignored

cout << "Enter names: ";
string names;
getline(cin, names);
票数 25
EN

Stack Overflow用户

发布于 2011-04-21 13:53:23

另一种方法是将一个

代码语言:javascript
复制
cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' ); 

在您的cin>>number;之后,完全刷新输入缓冲区(拒绝所有额外的字符,直到找到换行符)。您需要使用#include <limits>来获取max()方法。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5739937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档