c++ getline()在多次调用时不等待来自控制台的输入

g0czyy6m  于 2023-03-20  发布在  其他
关注(0)|答案(9)|浏览(175)

我尝试从控制台获取一些用户输入参数,两个字符串,两个整型和一个双精度型。我尝试使用的相关代码如下:

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

// ...

string inputString;
unsigned int inputUInt;
double inputDouble;

// ...

cout << "Title: "; 
getline(cin, inputString);
tempDVD.setTitle(inputString);

cout << "Category: "; 
getline(cin, inputString);
tempDVD.setCategory(inputString);

cout << "Duration (minutes): "; 
cin >> inputUInt; 
tempDVD.setDuration(inputUInt);

cout << "Year: "; 
cin >> inputUInt; 
tempDVD.setYear(inputUInt);

cout << "Price: $"; 
cin >> inputDouble; 
tempDVD.setPrice(inputDouble);

但是,当运行程序时,代码并没有等待输入第一个inputString,而是在第二次getline()调用之前才停止,因此控制台输出如下所示:
标题:类别:
光标出现在category之后。如果我现在输入,程序会跳到year输入,不允许我输入一个以上的字符串。这是怎么回事?

ldxq2e6h

ldxq2e6h1#

问题是您将getline()调用与操作符〉〉的使用混淆了。
请记住,操作符〉〉忽略了前导白色,因此将正确地跨行继续。但在成功检索输入后停止阅读,因此不会吞下尾随的“\n”字符。因此,如果在〉〉后使用getline(),通常会得到错误的结果,除非你小心(首先删除未读取的“\n”字符)。
诀窍是不要同时使用两种输入方式,选择合适的一种并坚持使用。
如果它是所有的数字(或对象,发挥良好的操作符〉〉),那么只使用操作符〉〉(注意字符串是唯一的基本类型,不对称的输入/输出(即不发挥良好))。
如果输入包含字符串或需要getline()的内容组合,则只使用getline()并从字符串中解析出数字。

std::getline(std::cin, line);
std::stringstream  linestream(line);

int  value;
linestream >> value;

// Or if you have boost:
std::getline(std::cin, line);
int  value = boost::lexical_cast<int>(line);
gupuwyp2

gupuwyp22#

你需要刷新输入缓冲区,可以用cin.clear(); cin.sync();来完成。

rsaldnfx

rsaldnfx3#

您可以使用

cin.ignore();

或者如Kernald提到的那样使用

cin.clear();
cin.sync();

使用getline()之前

vltsax25

vltsax254#

使用如上所述的cin.clear()使用正确的错误处理:

cin.clear();
    cin.sync();

    cout << "Title: "; 
    if (!getline(cin, inputString))  exit 255;
    tempDVD.setTitle(inputString);

    cout << "Category: "; 
    if (!getline(cin, inputString))  exit 255;
    tempDVD.setCategory(inputString);

    cout << "Duration (minutes): "; 
    if (!(cin >> inputUInt)) exit 255; 
    tempDVD.setDuration(inputUInt);

    cout << "Year: "; 
    if (!(cin >> inputUInt)) exit 255; 
    tempDVD.setYear(inputUInt);

    cout << "Price: $"; 
    if (!(cin >> inputDouble)) exit 255; 
    tempDVD.setPrice(inputDouble);
qrjkbowd

qrjkbowd5#

也适用于ws。您可以使用getline(cin >> ws, inputString))在使用cin命令阅读数据后删除空格或换行符。

dbf7pr2w

dbf7pr2w6#

如果用户在 getline 之前的 cin 中的\n之前输入空格,则仅 ignore 本身将不够,因此必须使用此代码而不是单独使用 ignore()。例如,12345 \t \n将不再有效。必须忽略所有未处理的字符。

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

cingetline 之间使用此选项。

fd3cxomn

fd3cxomn7#

将getline()与输入流混合通常是一件坏事。理论上可以手动处理使用流留下的脏缓冲区,但这是一个不必要的痛苦,绝对应该避免。
您最好使用控制台库来获取输入,这样可以为您提取脏工作。
看看TinyCon,你可以用静态方法tinyConsole::getLine()来代替getline和stream调用,而且你可以随意使用它。
您可以在这里找到信息:https://sourceforge.net/projects/tinycon/

7cjasjjr

7cjasjjr8#

cin.sync();使用此函数代替cin.ignore(效果最佳。

xzv2uavs

xzv2uavs9#

函数_______将返回最后读取的字符,并将内部指针移动一个-1字符。
1.获取行()
1.查看()3.刷新()4.放回()

相关问题