6

我正在学习 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 -->”直到它被杀死。(使用这个特定的输入序列,程序的输出速度会发生不规律的变化。)我还注意到,大值的输出取决于先前的合法输入以及当前非法输入的值。

这是怎么回事?(我不关心修复程序,这很容易。我想了解它。)

4

4 回答 4

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,您可以在条件中测试“善良”。所以基本上“ 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
        }
    }
}
于 2008-11-05T21:14:33.690 回答
5

是的,Evan Teran 已经指出了大多数事情。我想补充的一件事(因为我还不能评论他的评论:))是你必须在调用 istream::ignore之前调用 istream::clear。原因是如果流仍处于失败状态, istream::ignore 同样将拒绝执行任何操作。

于 2008-11-05T22:29:58.047 回答
3

鉴于您使用的是 32 位机器,10000000000 是一个太大的数字,无法用 int 表示。此外,根据编译器,将 int 转换为 char 只会为您提供 0..255 或 -128..127 的值。

于 2008-11-05T21:14:05.160 回答
0

这里的一个问题是 achar的大小为一个字节,因此只能容纳 -127 到 128 之间的数字。int另一方面,an 通常是 4 个字节,并且可以采用更大的值。第二个问题是您输入的值对于int.

于 2008-11-05T21:15:50.273 回答