我正在学习C ++并编写一些程序。以下是一个这样的程序:
// This program is intended to take any integer and convert to the
// corresponding signed char.
#include <iostream>
int main()
{
signed char sch = 0;
int n = 0;
while(true){
std::cin >> n;
sch = n;
std::cout << n << " --> " << sch << std::endl;
}
}
当我运行此程序并将输入保持在相当小的绝对值时,它的行为与预期的一样。但是当我输入较大的输入,例如10000000000时,程序会重复地输出相同的输出。某些输入组合会导致不稳定的行为。例如:
#: ./int2ch
10
10 -->
10000000000
10 -->
10 -->
10 -->
10 -->
程序吐出“10 - &gt;”直到它被杀死。 (使用这个特定的输入序列,程序的输出变化速度不稳定。)我还注意到,大值的输出由先前的合法输入以及当前非法输入的值决定。
发生了什么事? (我不关心修复程序,这很容易。我想理解它。)
答案 0 :(得分:13)
基本上,您的cin
流处于失败状态,因此当您尝试读取它时会立即返回。像这样重写你的例子:
#include <iostream>
int main()
{
signed char sch = 0;
int n = 0;
while(std::cin >> n){
sch = n;
std::cout << n << " --> " << sch << std::endl;
}
}
cin >> n
将返回对cin
的引用,您可以在条件中测试“good-ness”。所以基本上“while(std::cin >> n)
”说的是“虽然我仍能成功读取标准输入,但请执行以下操作”
编辑:它重复输出输入的最后一个好值的原因是因为那是n中成功读取的最后一个值,失败的读取不会改变n的值
编辑:如评论中所述,您可以清除错误状态并再次尝试这样的事情可能会起作用并忽略不良数字:#include <iostream>
#include <climits>
int main() {
signed char sch = 0;
int n = 0;
while(true) {
if(std::cin >> n) {
sch = n;
std::cout << n << " --> " << sch << std::endl;
} else {
std::cin.clear(); // clear error state
std::cin.ignore(INT_MAX, '\n'); // ignore this line we couldn't read it
}
}
}
答案 1 :(得分:5)
是的,Evan Teran已经指出了大部分事情。我想添加的一件事(因为我无法评论他的评论:))是你必须在调用istream :: ignore之前调用istream :: clear 。原因是如果流仍然处于失败状态,istream :: ignore同样会拒绝执行任何操作。
答案 2 :(得分:3)
鉴于您使用的是32位计算机,10000000000的数字太大而无法用int表示。同时将int转换为char只会给你0..255或-128..127,具体取决于编译器。
答案 3 :(得分:0)
这里的一个问题是char
的大小为一个字节,因此只能保存-127到128之间的数字。另一方面,int
通常是4个字节,并且可以承担更大的价值。第二个问题是,即使是int
,您输入的值也太大了。