为什么ifstream读取0x80000000 int失败?

why does ifstream read fail for int with 0x80000000

本文关键字:失败 int 0x80000000 ifstream 读取 为什么      更新时间:2023-10-16

在一个简单的控制台应用程序中,我试图读取每行包含十六进制值的文件。

它在前几个工作,但在4或5之后它开始输出cdcdcdcd。

知道这是为什么吗?以这种基本方式使用read有限制吗?

文件的第一个字节是它的大小。

std::ifstream read("file.bin");
int* data;
try
{
    data = new int [11398];
}
    catch (int e)
{
    std::cout << "Error - dynamic array not created. Code: [" << e << "]n"; 
}
int size = 0;
read>>std::hex>>size;
std::cout<<std::hex<<size<<std::endl;
for( int i = 0; i < size; i++)
{
    read>>std::hex>>data[i];
    std::cout<<std::hex<<data[i]<<std::endl;
}

我得到的返回值是:

576 (size)    
1000323    
2000000    
1000005    
cdcdcdcd
cdcdcdcd    
cdcdcdcd    
...

在cdcdcdcd的位置上输出的第一个值是80000000

int类型溢出

如果您更改为unsigned int。您将能够填充到0xFFFFFFFF

您可以查看:

std::cout << "Range of integer: " 
          << std::numeric_limits<int>::max() 
          << "  <Value> " 
          << std::numeric_limits<int>::min() 
          << "n";

std::cout << "Range of integer: " 
          << std::numeric_limits<unsigned int>::max() 
          << "  <Value> " 
          << std::numeric_limits<unsigned int>::min() 
          << "n";

注意:没有负的十六进制值(它被设计为位表示的紧凑表示)。

你应该检查一下读取是否有效:

 if (read>>std::hex>>data[i])
 {
     // read worked
 }
 else
 {
     // read failed.
 }

听起来很像是你的阅读失败了。

注意,在32位的int系统上,0x80000000超出了int的范围。有效值的范围可能是-0x80000000到0x7FFFFFFF。

重要的是不要将表示混淆。"0x80000000",当通过std::hex读取时,表示以16为基数写为80000000的正整数。一个特定的负整数可以在有符号的int中以2的补码形式存储,其二进制表示形式与unsigned int类型的正整数80000000存储在其中时的二进制表示形式相同。

如果您打算使用这种技术,请考虑读入unsigned int。此外,检查读取操作的成功或失败也是必不可少的。如果流提取失败,则流将进入错误状态,在此状态下,所有后续读取都将失败,直到您在流上调用.clear()

NB。std::hex(以及实际上所有其他修饰符)是"粘性的":一旦您设置了它,它将保持设置,直到您实际指定std::dec来恢复默认值。