繁体   English   中英

为什么ifstream对于0x80000000的int读取失败

[英]why does ifstream read fail for int with 0x80000000

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

它适用于前几个,但在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。

重要的是不要将表示混淆在一起。 通过std::hex读取时,“ 0x80000000”表示在基数16中写为80000000的正整数。在这里或那里,都没有一个特定的负整数可以内部存储在带相同int的2的补码中当正整数80000000存储在其中时,表示形式为unsigned int类型的正值。

如果您打算使用此技术,请考虑读入unsigned int 另外,还必须检查读取操作是否成功。 如果流提取失败,则流将进入错误状态,在该状态下所有后续读取都会失败,直到您.clear()调用.clear()为止。

注意 std::hex (实际上是所有其他修饰符)是“粘滞的”:设置后,它将保持设置状态,直到您实际指定std::dec来恢复默认值为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM