2017-03-01 34 views
1

我正在研究现在的C++的二进制文件。我为它制作了一个示例代码,但效果不佳。从C++中的二进制文件获取整数值时的垃圾值

#include <iostream> 
#include <fstream> 
using namespace std; 

int main() { 
    ofstream writeFile; 
    ifstream readFile; 
    int temp = 1; 

    writeFile.open("file.dat", ios::binary); 

    for (int i = 5; i <= 10 ; i++) // range 5 to 10 
     writeFile.write((char*)(&i), sizeof(i)); 

    writeFile.close(); 

    readFile.open("file.dat", ios::binary); 
    readFile.seekg(0); 
    while (!readFile.eof()) { 
     readFile.read((char*)(&temp), sizeof(temp)); 
     cout << "temp: " << temp << endl; 
     readFile >> ws; 
    } 
    readFile.close(); 

    system("pause"); 
    return 0; 
} 

下面是结果:

temp: 5 
temp: 6 
temp: 7 
temp: 8 
temp: 167772160 
temp: 167772160 

当我改变的范围不包括图9(例如,5〜8),它工作得很好。另外,当我使用double类型编码时,它运行良好。所以我认为整数9是问题。你能告诉我为什么吗?

回答

4

readFile >> ws;丢弃白色空间,这对于二进制流是无意义的。在这种情况下,字符值9(即'\t')会被跳过,从而损坏您的流。只需删除该行。

第二个问题是您没有在读取和显示值之间检查流的状态。 EOF仅在之后检测到,读取将超过文件的结尾。这就是为什么你得到两次无效值,第二次读取失败,并且只是将temp保留之前的值。 See this question了解更多详情。

+0

值9实际上是'\ t'。 10是'\ n'。两者都被认为是空白的事实是导致问题的原因。 – IInspectable

+0

或者,'readFile >> ws'只会跳过'\ t'字符,然后读取四个字节0​​0 00 00 0a,解释为小端4字节整数值为167772160。明确定义(我相信)。但是,下一次尝试读取超出EOF。这是UB,并显示167772160是未定义行为的有效形式。 – IInspectable

1

The answer by François Andrieux已经回答了为什么你的代码的行为方式如此。

这里有几个方法来解决这个问题。

  1. 使用for循环读取数字。它反映了用于写入的循环。

    readFile.open("file.dat", ios::binary); 
    for (int i = 5; i <= 10 ; i++) 
    { 
        readFile.read((char*)(&temp), sizeof(temp)); 
        cout << "temp: " << temp << endl; 
    } 
    readFile.close(); 
    
  2. 正确使用while循环。

    readFile.open("file.dat", ios::binary); 
    while (readFile.read((char*)(&temp), sizeof(temp))) 
    { 
        cout << "temp: " << temp << endl; 
    } 
    readFile.close();