// using structures
#include <iostream>
#include <string>
using namespace std;
struct playerinfo
{
string name;
int level;
};
int main()
{
playerinfo arr[5];
for (int i = 0; i < 5; i++)
{
cout << " enter name for player " << i << endl;
getline(cin, arr[i].name, '\n');
cout << " and level \n";
cin >> arr[i].level;
}
for (int i = 0; i < 5; i++)
cout << "the level of player " << arr[i].name << " is " << arr[i].level << endl;
}
我正在读一本关于c ++语法的书,我正在练习。我希望代码的行为使得代码要求用户填写播放器的名称和级别,然后代码将它们全部打印出来。但它的表现并不像这样。当我运行代码并输入播放器的名称说“汤姆猫”然后代码询问级别,我打印一个整数说“100”,然后意外的事情开始发生,其中的原因,我无法理解。你能帮忙吗? 编辑 - 很少有人让我详细说明“意想不到的事情”开始发生的事情。 意想不到的是,当我输入播放器的名称和播放器0的级别时,屏幕上的下一个输出是“输入播放器1和级别的名称”,而我希望它只能输出“和级别”之后我输入了播放器1的名称。
答案 0 :(得分:6)
当使用operator>>()
从格式化输入切换时,例如,在cin >> arr[i].level
和未格式化的输入中,例如,使用std::getline()
,您需要知道可能在输入中等待的空格:格式化一旦找到空格(例如换行符),整数的输入就会停止。另一方面,std::getline()
会在找到换行符后立即停止!所以你得到一个空行。修复是在切换到无格式输入时跳过前导空格,例如:
std::getline(std::cin >> std::ws, arr[i].name);
操纵者std::ws
在使用std::istream
时会跳过前导空格。
在使用输入之前,您还应始终验证输入是否成功:如果输入失败,则流停止运行并转换为false
:
if (std::cin >> arr[i].level) {
// process the data
}
else {
// report that the input is wrong and bail out
}
答案 1 :(得分:1)
当您在级别中键入并按Enter键时,您实际上是在输入100\n
。 in >> arr[i].level
会提取数字100
并将其放入arr[i].level
,因为它会触及换行符而停止,但它不会提取换行符本身。换行符保留在输入流中!下一次迭代将开始,getline
将看到已经有一些可用的输入要读取,它将尝试读取一行到下一个\n
字符。我们知道,下一个\n
是输入中剩下的第一个字符,因此getline
将读取一个空字符串。从现在开始,你的程序处于搞砸状态。
解决此问题的一种快捷方法是在使用ignore
读取关卡后直到并包含换行符后,从输入中丢弃字符:
cin >> arr[i].level;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
这将允许用户输入100foobar
,它将被解释为100
。这可能是你想要的,也可能不是。如果你想接受/拒绝其他一些格式,我会把它留给你。
答案 2 :(得分:1)
包含标题
#include <limits>
在此声明之前
getline(cin, arr[i].name, '\n');
插入声明
cin.ignore( numeric_limits<streamsize>::max() );
问题是声明之后
cin >> arr[i].level;
输入缓冲区将在用户按Enter后保留新行字符('\ n'),下一个getline函数将在此新行字符前读取空字符串。