C++ 将字符赋给int变量时的奇怪行为
鉴于此代码:C++ 将字符赋给int变量时的奇怪行为,c++,C++,鉴于此代码: #include <cstdio> #include <iostream> #include <string> using std::cin; using std::cout; using std::string; int main() { int a; string b; cin >> a; cin >> b; return 0; }
#include <cstdio>
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::string;
int main() {
int a;
string b;
cin >> a;
cin >> b;
return 0;
}
输入
1测试
输出
a是1
b是测试
*没有执行getchar*
输入
1.
试验
输出
a是1
b是测试
输入
测试
输出
a是0
b是
输入
t
//跳过第二个cin
输出
a是0
b是
注:
getchar()
甚至没有执行一次。您可能在第一个字符后按enter键。您没有任何代码来使用该enter,因此将得到一个空字符串。您的代码不希望两个输入之间有任何分隔符,因此不要输入任何分隔符。当您输入char
并希望读取int
时,cin
流将设置其故障位。如果操作失败,调用cin.fail()
将返回true
(设置了etherfailbit
或badbit
)。你可以据此行动
请注意,cin
可以转换为bool
进行测试,根据标准,此布尔值与相同!cin.fail()
,和!cin
与cin.fail()相同。以下两个是相同的,但有些人可能认为第二个更可读。
if(!cin) {
// cin is in failed state
}
if(cin.fail()) {
// cin is in failed state
}
一旦cin
处于失败状态,任何带有cin
的读取操作都将是不可操作的,直到您将流重置为良好状态。您可以通过调用cin.clear()
来实现这一点
但你也必须意识到,冒犯的角色仍然存在。也就是说,导致失败状态的非整数字符仍将在流中。如何处理此问题取决于您希望如何从错误中恢复。一种可能是打电话
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin.ignore(std::numeric_limits::max(),'\n');
这将清除当前行。然后您可以再次提示输入。从您的输出判断,有两件事。第一个是当你进入时
“ttest”
,cin>>a代码>失败。这会使cin
处于错误状态,
在清除错误之前,它将一直保留。只要是
在错误状态下,所有其他操作均为无操作。你真的需要
在尝试使用这些值之前,请测试输入的结果:
std::cin >> a;
if ( !cin ) {
std::cerr << "That wasn't an integer" << std::endl;
std::cin.clear();
}
std::cin >> b;
if ( !cin ) {
std::cerr << "Where was the string" << std::endl;
std::cin.clear();
}
我试过代码,两个CIN似乎都对我有效。你是如何运行这个程序的?你在哪个操作系统上运行它?你正在使用终端吗?我正在通过终端在Mac OS X上运行它。如果你输入一个char
,其中需要int
,它会使cin
流进入错误状态。在您将状态重置为良好之前,使用cin
的每个操作都是noop(无操作)。这就是我一直在寻找的答案!你说的状态重置是什么意思?这与未执行getchar()有关?抱歉,您需要调用cin.clear()
。这将清除failbit
(和badbit
),以便读取更多输入。您可能想先检查读取是否失败。-1建议使用cin.good()
。这永远不是正确的解决方案,因为即使结果是正确的,它也可能返回false。@JamesKanze:是的,我应该说检查cin.fail()
,它与相同!cin
。这不可能是对的,因为他使用的是
,它跳过了前导空格(包括新行)。@JamesKanze:他添加了一个getchar
,但他发布的代码中没有。@David Schwartz:我刚刚添加了另一个程序,我从来没有修改过第一个。选择这个作为答案,因为它是最详尽的。约翰普斯的回答也很好@除了约翰·纳普斯的答案是错误的以外。使用cin.good()
通常不起作用;事实上,这个函数没有已知的用途。但我承认,他提到nop操作在读取失败后替换正常预期的cin代码,并使用cin.clear()清除读取缓冲区。顺便说一下,感谢您的详细解释(我很高兴您解释了getchar()问题)。
std::cin >> a;
if ( !cin ) {
std::cerr << "That wasn't an integer" << std::endl;
std::cin.clear();
}
std::cin >> b;
if ( !cin ) {
std::cerr << "Where was the string" << std::endl;
std::cin.clear();
}
std::string line:
std::getline(std::cin, line);
if ( ! std::cin ) {
// Something unexpected went wrong...
std::cin.clear();
} else {
std::istringstream l( line );
l >> a >> b;
if ( !l ) {
// Format error in input...
} else {
// use your data here...
}
}
std::cin.get(); // Wait for one more character...