在 cin 之后使用 getline(cin, s) [英] Using getline(cin, s) after cin
问题描述
我需要以下程序来获取用户输入的整行并将其放入字符串名称中:
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()
命令之前的 number
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 != '
')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found
";
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
";
exit(EXIT_FAILURE);
}
在上面的代码中,这个位...
In the code above, this bit...
char c;
while (cin.get(c) && c != '
')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found
";
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()
(和 std::cin.ignore()
)对此不是必需的,但对于删除错误状态.例如,如果您想给用户很多机会输入有效数字.
So, std::cin.clear()
(and std::cin.ignore()
) 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
";
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
在阅读行之前跳过任意数量的空格...>
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屋!