3

我看了其他一些问题,我对 C++ 太陌生了,不知道它们是否适用于我的问题。

基本上当显示“名称”的输出时,如果我输入我的全名,它只会显示第二个单词。之前,它甚至什么都不吃,只是略过而已。我现在对看似简单的事情感到困惑。谢谢。

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

int main()
{
double money;
string name;
int age;

// Prompt for age and receive
cout<<"How old are you? ";
cin >> age;

// Prompt for money and receive
cout<<"How much money do you have?";
cin >> money >> endl;

// Prompt for name and receive
cout<<"What's your name?\n\n"<< endl;
getline(cin, name);

// Display all information to user
cout<<"Hello, "<< name <<".";
cout << "You are " << age << " years old";
cout<< " and have $" << money << ".\n";

system("PAUSE");
return 0;
}
4

2 回答 2

4

问题是格式化输入 using>>读取一个值并在该值被完全解析后停止。例如,一旦出现与格式不匹配的内容,数字就完成了。也就是说,阅读将在空格或换行符(以及相当多的其他字符)前面停止。通常这些额外的字符不会引起问题,因为格式化输入在尝试读取实际值之前会跳过前导空格(空格、制表符、换行符等)。

但是,例如,未格式化的输入getline()会立即开始读取其值,并在遇到换行符(或如果使用三参数版本时指定为换行符的字符)时停止。也就是说,getline()如果换行符留在流中,它将在读取换行符后立即停止。

摆脱换行符(和任何其他前导空格)的最简单方法是使用std::ws,例如:

if (std::getline(std::cin >> std::ws, name)) {
    ...
}

...而且,顺便说一句,每当您尝试读取某些内容时,您应该始终读取尝试读取值成功后检查!

另一种方法是根本不使用std::getline(),而是只使用格式化的输入name。但是,这假设名称中没有任何空格。

于 2013-08-29T22:34:44.077 回答
0

那是因为newline从“你有多少钱?” 回复仍在输入缓冲区中。一般来说,混合项目输入和基于行的输入(无论是使用 C 和scanf/fgets或 C++>>getline)并不是一个好主意,因为您会遇到这类问题。

char dummy = cin.get();您可以通过在某处使用 before来解决这种特殊情况getline,但是,每次从“项目输入”切换到“行输入”时都必须这样做,并且如果您稍后更改顺序,则必须记住cin.get()移动.

更好的解决方案是始终使用基于行的输入,然后使用stringstream从字符串中获取数据,因此如下所示:

string ageString;
getline(cin, ageString);
stringstream ageSs(ageString);
if (!ageSs >> age)
{
    cout << "Bad input" << endl;
    exit(1);    // You may of course want to repeat rather than exit... 
}

这样,无论输入是什么,您都在阅读整行。

于 2013-08-29T22:28:02.163 回答