将char赋值给int变量时的奇怪行为 [英] Weird behaviour when assigning a char to a int variable
问题描述
给定此代码:
#include< cstdio&
#include< iostream>
#include< string>
using std :: cin;
using std :: cout;
using std :: string;
int main(){
int a;
string b;
cin>>一个;
cin>> b;
return 0;
}
我试过用g ++编译它并运行它。
当在 cin
的第一个 a
中指定一个字符时,以下指令似乎被跳过。
即使在最后两行之间添加两个 getchar()
指令,只有第二个 getchar()
似乎被执行。
有人可以准确地解释在低级别发生了什么,这似乎导致明显不执行这些行?
EDIT:
使用此调试代码:
#include< cstdio&
#include< iostream>
#include< string>
using std :: cin;
using std :: cout;
using std :: endl;
using std :: string;
int main(){
int a;
string b;
cin>>一个;
cin>> b;
cout<< a是< a<< endl;
cout<< b是< b<< endl;
getchar();
return 0;
}
INPUT
1test
OUTPUT
a是1
b是test
*没有执行getchar *
b $ b
INPUT
1
测试
OUTPUT
a is 1
b is test
INPUT
ttest
OUTPUT
a是0
b是
INPUT
t
//跳过第二个 cin
OUTPUT
a is 0
b
注意:
getchar()
未执行一次。
有两件事,从你的输出判断。第一个是当你输入
ttest
, cin> a;
失败。这会将 cin
置于错误状态
,它将保留,直到错误被清除。并且只要它是
处于错误状态,所有其他操作都是无操作。你真的需要
在尝试使用值之前测试输入的结果:
std :: cin> ;>一个;
if(!cin){
std :: cerr<< 不是整数<< std :: endl;
std :: cin.clear();
}
std :: cin>> b;
if(!cin){
std :: cerr<< 字符串<< std :: endl;
std :: cin.clear();
}
(不要使用非初始化的变量,例如 a
,直到成功输入
。)
第二个是 >< / code>操作符仅提取其目标所需的字符
:>> int
将停止在第一个
非数字字符和>>
到 std: :string
在第一个白色
空间(在这两种情况下,在跳过前面的空格之后)。这个
意味着在1test\\\
之后,还会有一个
'\\\
。虽然将
'
FILE *
(如 getchar()
)和iostream混合通常是个不好的想法,如果他们正确地
同步, getchar()
将立即读取这个'\\\
'
如果你正在阅读面向行的输入,最好的解决方案是使用
getline()
,然后将该行放入 std :: istringstream
以解析
。所以你的代码可能会看起来像:
std :: string line:
std :: getline(std: :cin,line);
if(!std :: cin){
//意外出错了...
std :: cin.clear();
} else {
std :: istringstream l(line);
l>> a>> b;
if(!l){
//输入格式错误...
} else {
//在这里使用你的数据...
}
}
std :: cin.get(); //等一个字符...
Given this code:
#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;
}
I tried compiling it with g++ and running it.
When assigning a char to a
, at the first cin
, the following instruction seems to be skipped.
Even if add two getchar()
instructions between the last two lines, only the second getchar()
seems to be executed.
Can somebody accurately explain what's happening at low level, which seemingly results in an apparent non execution of those lines?
EDIT:
Using this debug code:
#include <cstdio>
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main() {
int a;
string b;
cin >> a;
cin >> b;
cout << "a is "<< a << endl;
cout << "b is "<< b << endl;
getchar();
return 0;
}
INPUT 1test
OUTPUT a is 1 b is test * No getchar executed *
INPUT 1 test
OUTPUT a is 1 b is test
INPUT ttest
OUTPUT a is 0 b is
INPUT t
// Skips the second cin
OUTPUT a is 0 b is
NOTE:
getchar()
was not executed even once.
Two things, judging from your output. The first is when you enter
"ttest"
, the cin >> a;
fails. This puts cin
in an error state,
where it will remain until the error is cleared. And as long as it is
in an error state, all other operations are no-ops. You really need to
test the results of the input before trying to use the values:
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();
}
(And don't use a non-initialized variable, like a
, until it has been
successfully input.)
The second is that the >>
operator only extracts the characters
necessary for its target: >>
to an int
will stop at the first
non-numeric character, and >>
to a std::string
at the first white
space (in both cases, after having skipped leading white space). This
means that after something like "1test\n"
, there will still be a
'\n'
in the buffer. And while it's generally a bad idea to mix
FILE*
(like getchar()
) and iostream, if they're correctly
synchronized, getchar()
will read this '\n'
immediately and return.
If you're reading line oriented input, the best solution is to use
getline()
, and then put the line into a std::istringstream
to parse
it. So your code might end up looking like:
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...
这篇关于将char赋值给int变量时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!