澄清 C++ 中 cin 的基本行为
Clarification on a basic behavior of cin in C++
我很好奇为什么 cin
会有以下行为。我想我可能有
对其行为的一些误解。
考虑这个简单的代码。此代码要求输入一些输入,所有这些都在最后一个语句中打印出来。
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
cout << "Please enter your input: " ;
int a=3, b=87; // initialized to some random integers
string s = "Mary" ; // initialized to a random string
cin >> a ;
cin >> b ;
getline(cin,s);
cout << "You entered the following " << a << " " << b << " " << s << endl;
return 0;
}
现在如果输入是 12 34 cat
输出是 12 34 cat
这是意料之中的。
但是,如果输入为 cat 23 dog
,则输出为 0 87 Mary
。
这就是我认为这是出乎意料的原因:
cin >> a
应该会失败,因为 cat
无法转换为整数。但是,a
被替换为我认为是垃圾值的值。
现在输入的第二个数是整数23,cin >> b
一定成功。然而这个操作似乎失败了,并且 b
继续保留其原始值,这与 a
发生的情况不同。
类似地getline
无法将字符串<space>dog
放入字符串s
它继续保留其原始值 Mary
。
我的问题如下。
某些cin
操作的失败是否强制所有的失败
使用 >>
运算符或 getline
函数的后续 cin
操作。
为什么第一个cin
操作失败改变了a
的值
而 b
和 s
的初始值没有改变?
Does the failure of some cin operation mandate the failure of all
subsequent cin operations using the >> operator or the getline
function.
是的。直到您使用 cin.clear()
清除错误。此外,当提取失败时,字符会留在缓冲区中,因此如果您尝试再次读取相同类型,它将再次失败。
Why did the failure of the first cin operation change the value of a
whereas the initial values of b and s were unchanged?
因为(自 C++11 起),它被定义为在从(先前)有效流提取失败的情况下将值更改为 0。在 C++11 之前,它会保持不变。对于处于错误状态的流,该操作不执行任何操作,这就是 b
和 s
未更改的原因。
您应该使用cin.good()
函数或shorthand 表示法if(cin)
,如@AndyG 所述,以检查cin
对象的状态。变量 a
的类型是 int
那么你怎么输入字符串?因此,它为变量 a
.
提供了意外的输出
- Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.
是的。您的代码希望以完全相同的顺序读取输入值
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value
给它一个像
这样的输入
cat 23 dog
导致在尝试读取第一个 int
值时在 cin
上设置 fail()
状态,并且以下 operator>>()
调用中的 none 将成功.
cin >> a
should fail since cat
cannot be converted into an integer. However, a
gets replaced with what I presume is a garbage value.
这不是垃圾值,但定义明确,请参阅下面的参考引文。
Now since the second number of the input is an integer 23, cin >> b
must succeed. Yet this operation seems to fail, and b
continues to retain its original value unlike what happened to a
.
不,这个假设是错误的,如前所述,cin
此时处于 fail()
状态,并且完全跳过进一步输入的解析。
您必须在每次 operator>>()
调用后调用 clear()
,以确保输入将被解析:
cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value
- Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?
因为 std::basic_istream::operator>>()
的引用说
"If extraction fails, zero is written to value and failbit
is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max()
or std::numeric_limits<T>::min()
is written and failbit
flag is set. (since C++11)"
我很好奇为什么 cin
会有以下行为。我想我可能有
对其行为的一些误解。
考虑这个简单的代码。此代码要求输入一些输入,所有这些都在最后一个语句中打印出来。
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
cout << "Please enter your input: " ;
int a=3, b=87; // initialized to some random integers
string s = "Mary" ; // initialized to a random string
cin >> a ;
cin >> b ;
getline(cin,s);
cout << "You entered the following " << a << " " << b << " " << s << endl;
return 0;
}
现在如果输入是 12 34 cat
输出是 12 34 cat
这是意料之中的。
但是,如果输入为 cat 23 dog
,则输出为 0 87 Mary
。
这就是我认为这是出乎意料的原因:
cin >> a
应该会失败,因为 cat
无法转换为整数。但是,a
被替换为我认为是垃圾值的值。
现在输入的第二个数是整数23,cin >> b
一定成功。然而这个操作似乎失败了,并且 b
继续保留其原始值,这与 a
发生的情况不同。
类似地getline
无法将字符串<space>dog
放入字符串s
它继续保留其原始值 Mary
。
我的问题如下。
某些
cin
操作的失败是否强制所有的失败 使用>>
运算符或getline
函数的后续cin
操作。为什么第一个
cin
操作失败改变了a
的值 而b
和s
的初始值没有改变?
Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.
是的。直到您使用 cin.clear()
清除错误。此外,当提取失败时,字符会留在缓冲区中,因此如果您尝试再次读取相同类型,它将再次失败。
Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?
因为(自 C++11 起),它被定义为在从(先前)有效流提取失败的情况下将值更改为 0。在 C++11 之前,它会保持不变。对于处于错误状态的流,该操作不执行任何操作,这就是 b
和 s
未更改的原因。
您应该使用cin.good()
函数或shorthand 表示法if(cin)
,如@AndyG 所述,以检查cin
对象的状态。变量 a
的类型是 int
那么你怎么输入字符串?因此,它为变量 a
.
- Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.
是的。您的代码希望以完全相同的顺序读取输入值
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value
给它一个像
这样的输入cat 23 dog
导致在尝试读取第一个 int
值时在 cin
上设置 fail()
状态,并且以下 operator>>()
调用中的 none 将成功.
cin >> a
should fail sincecat
cannot be converted into an integer. However,a
gets replaced with what I presume is a garbage value.
这不是垃圾值,但定义明确,请参阅下面的参考引文。
Now since the second number of the input is an integer 23,
cin >> b
must succeed. Yet this operation seems to fail, andb
continues to retain its original value unlike what happened toa
.
不,这个假设是错误的,如前所述,cin
此时处于 fail()
状态,并且完全跳过进一步输入的解析。
您必须在每次 operator>>()
调用后调用 clear()
,以确保输入将被解析:
cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value
- Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?
因为 std::basic_istream::operator>>()
的引用说
"If extraction fails, zero is written to value and
failbit
is set. If extraction results in the value too large or too small to fit in value,std::numeric_limits<T>::max()
orstd::numeric_limits<T>::min()
is written andfailbit
flag is set. (since C++11)"