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

时间:2014-06-15 20:55:12

标签: c++ visual-studio-2010 ifstream

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

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

2 个答案:

答案 0 :(得分:3)

你正在溢出一个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.
 }

答案 1 :(得分:2)

听起来非常像你的阅读失败。

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

重要的是不要将表示混淆。当通过std::hex读取时,“0x80000000”表示在基数16中写为80000000的正整数。既不存在,也不存在特定的负整数可以存储在2的带符号int内部。当正整数80000000存储在其中时,补充使用相同的二进制表示作为类型unsigned int的正值。

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

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