48

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

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

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

getline(cin, names);

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

我听说过一些关于cin.clear()命令的事情,但我不知道它是如何工作的,或者为什么这甚至是必要的。

4

13 回答 13

26
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);
于 2012-07-08T19:11:47.327 回答
20

另一种方法是放置一个

cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' ); 

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

于 2011-04-21T05:53:23.060 回答
11
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);
}

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

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

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

为什么不直接使用忽略?

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

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

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

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跳过任何数量的空格......

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

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

于 2011-04-21T05:50:34.780 回答
10

尝试:

int number;

cin >> number;

char firstCharacterOfNames;
cin >> firstCharacterOfNames;  // This will discard all leading white space.
                               // including new-line if there happen to be any.

cin.unget();                   // Put back the first character of the name.

std::string  names;
std::getline(cin, names);      // Read the names;

或者。如果您知道数字和名称将始终位于不同的行上。

cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
std::getline(cin, names);
于 2011-04-21T08:47:58.947 回答
7

在使用 getline 之前,您可以使用 std::ws 提取输入缓冲区中的任何空白字符。std::ws 的标头是 sstream。

cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
于 2015-04-16T17:50:21.657 回答
6

在 getline() 函数之前使用 cin 时尝试 cin.ignore()

void inputstu(){
    cout << "Enter roll Number:";
    cin >> roll_no;
    cin.ignore(); //ignore the withspace and enter key
    cout << "Enter name:";
    getline(cin, stu_name);
}
于 2018-12-09T16:09:43.400 回答
1

我刚用

getline(cin >> ws,lard.i_npute);

与标准

#include <iostream>

在我遇到回车问题并且 ws 操纵器工作的情况下的标题。我可能会开始将循环函数嵌入为类,并至少使用构造函数和析构函数调用。

于 2016-10-27T17:25:31.413 回答
1
cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names

它非常自我解释,在使用的流中留下了一个 \n cin >> number,它在第一次使用时被分配给名称。现在重用 getline 会写入正确的值。

于 2018-03-19T17:11:05.620 回答
1

或者您可以刷新输入缓冲区以读取字符串

刷新(标准输入)

它在头文件stdio.h中定义。

此代码有效..

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

cout << "Enter names: ";
string names;
fflush(stdin);  //FLUSHING STDIN
getline(cin, names);
于 2016-09-12T13:17:18.843 回答
0

从概念上讲,我认为您希望每个答案都整齐地排成一行。那你为什么不试试这个呢?

cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);

cout << "Enter names: ";
string names;
getline(cin, names);

代码正确使用第一个换行符,如果行正确,则为您提供数字,否则抛出异常。全部免费!

于 2017-11-09T12:56:45.253 回答
0

您想在 cin 语句之后使用 cin.ignore() ,因为您想在使用 cin 获取 int 变量后忽略缓冲区中留下的“\n”。

我有一个类似的程序,我用过类似的问题:

#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

int main() {
    int i = 4;
    double d = 4.0;
    string s = "HackerRank ";

    // Declare second integer, double, and String variables.
    int n;
    double d2;
    string str;

    // Read and save an integer, double, and String to your variables.
    cin >> n;
    cin >> d2;

    cin.ignore();

    getline(cin, str);

    // Print the sum of both integer variables on a new line.
    cout << i + n << endl;


    // Print the sum of the double variables on a new line.
    cout << d + d2 << endl;

    // Concatenate and print the String variables on a new line
    cout << s << str << endl;

    // The 's' variable above should be printed first.

    return 0;
}
于 2016-09-16T18:49:15.640 回答
0

您可以在cppreference中找到您想要的答案。

当在空格分隔的输入之后立即使用时,例如在 之后int n; std::cin >> n;,getline 使用 operator>> 留在输入流上的结束行字符,并立即返回。cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');一个常见的解决方案是在切换到面向行的输入之前忽略输入行上的所有剩余字符。

于 2016-08-20T02:17:39.983 回答
-1
#include <iostream>
#include <string>

using namespace std;

int main()
{
    cout << "Enter the number: ";
    int number;
    cin >> number;
    cout << "Enter names: ";
    string names;

    // USE peek() TO SOLVE IT! ;)
    if (cin.peek() == '\n') {
        cin.ignore(1 /*numeric_limits<streamsize>::max()*/, '\n');
    }

    getline(cin, names);

    return 0;
}

只需使用cin.peek()并查看 a'\n'是否仍留在cin的内部缓冲区中。如果是这样:忽略它(基本上跳过它)

于 2015-02-03T09:55:03.603 回答