将char赋值给int变量时的奇怪行为 [英] Weird behaviour when assigning a char to a int variable

查看:242
本文介绍了将char赋值给int变量时的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定此代码:

  #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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆