【问题标题】:char overflow at ~125+字符溢出 ~125+
【发布时间】:2016-03-20 08:42:25
【问题描述】:

简短的长程序:我正在逐字节读取二进制文件,在每个读取字节后我输出这个字节但不是作为字符(因为我声明了一个变量char c并将值存储在其中)而是作为int .当我得到大约 125 以上的二进制值时,我得到的值为负值。

例如,当我读取hex 89 = dec 137 并将此字符输出为int 时,我得到值-119

另一个例子:我读到hex 83 = dec 131 并将这个字符输出为int,我得到值-125

我按字节读取这个文件:

ifstream inFile;
inFile . open( srcName, ios::binary | ios::in );

char c;

while( inFile . get( c ) ){
  inFile . get( c );
  cout << (int) c << endl;
}

【问题讨论】:

  • 我猜char 在您的系统上已签名
  • 假设一个有符号字符,一切都将在 -128 到 127 的范围内
  • 先尝试将其转换为unsigned char?并且请不要使用 C-style cast,了解static_cast
  • 你总是可以使用 if((int)c
  • 他们是否还在高中或大学水平的 CS 课程中教授补码数学?显然不是。

标签: c++ char


【解决方案1】:

我想你想问为什么在你期望积极的时候你会看到消极的价值。

首先,您不应将文件中的数据读入char。在 C 和 C++ 中,从文件或标准输入(getchar()fgetc()ifstream::get() 等)读取字符的函数返回 int。原因是需要检测文件(或输入)的结尾。该函数需要返回一些可以检查的值,并且与任何可能的字节(char)值不同 - 在二进制文件中,您可以遇到具有任何值的字节。

其次,char 在 C++ 中可能是也可能不是 signed(有关详细信息,请参阅 this question)。您的char 似乎是signed char。这意味着它可以表示 (-128,127) 范围内的数字,并将超过 127 的字节值解释为负数。这就是为什么你认为它们是负面的(C++ 会将(char) -119 转换为(int) -119)。如果您想要正值,请将您的 c 声明为 unsigned char(或 unsigned int)。

【讨论】:

  • ifstream::get() 需要 char 类型的参数
  • 您可以使用get() 签名,它返回int。那么您的代码将是:int c; while ((c = inFile.get()) != EOF) { cout &lt;&lt; c &lt;&lt; endl; } int 应该可以工作,即使 signed 也是如此。
【解决方案2】:

首先要说的是,标准不保证charsignedunsigned - 这是特定于系统和实现的。然后,您不应该将char 用于此类任务,因为即使它工作正常(这不是您的情况),当您使用不同的编译器或不同的系统时,它也可能会中断。

第二件事是你不应该使用 C 风格的强制转换,而是使用 static_cast。 C 风格的强制转换并不安全,并且在其简单的语法下存在很多复杂性。

要解决您的问题,您可以使用unsigned char 而不是char。如果由于某种原因这是不可能的 - 您可以尝试在(隐式)转换为 unsigned int 之前转换为 unsigned char,如下所示:

unsigned int val = static_cast<unsigned char>(a);

【讨论】:

  • 编译器打印错误.. ifstream::get() 需要char 参数
  • 好吧,“如果由于某种原因这是不可能的 - 您可以尝试在(隐式)转换为 unsigned int 之前转换为 unsigned char,如下所示:...”。只需将get 数字转换为char,然后使用我上面的代码将其转换为unsigned int。它应该可以工作。
猜你喜欢
  • 2021-11-08
  • 2011-09-05
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多