【问题标题】:Trouble reading Binary file in C++在 C++ 中读取二进制文件时遇到问题
【发布时间】:2017-09-01 18:01:18
【问题描述】:

我目前正在开发可以读取二进制文件的程序。我知道有很多主题可以回答同一个问题,但我的问题非常单一,我还没有找到任何答案。

所以我知道二进制文件的结构:

  • 4 字节:文件中的表数 然后是文件中的第一个表:
  • 4 字节:表中的数据类型
  • 4字节:表名长度
  • L 字节:表名
  • 4 字节:行数
  • 4 字节:列数
  • Nbr 行 * Nbr 列 * sizeof(type) 字节:数据

因此,使用读取指令,我设法获取了数据之前的所有内容。 例如,在我的第一个二进制文件中,我的第一个表是浮点数 3 行和 300 000 列。我设法获得了前 66 个,然后我在第 67 个获得了 endofFile 标志,并为我尝试读取的所有 899 932 个其他浮点数获得了坏字节标志。

这是我的标题代码的一些部分(效果很好)

uint32_t tableManager::getNbrTables()
{   
    uint32_t a;
    file.read(reinterpret_cast<char *>(&a), sizeof(a));
    return a;
}

uint32_t tableManager::getTypeData(int k)
{   
    uint32_t a;
    file.read(reinterpret_cast<char *>(&a), sizeof(a));
    return (a - 1);
}

这些为我提供了我需要的标题的正确值。然后我使用循环来获取数据值,代码如下:

vector<vector<float>> tmpL(nbrL[m]);
    vector<float> tmpC(nbrC[m]);    
    switch (typeData[m])
    {
    case 0: 
        char x0;
        for(int n = 0; n < nbrL[m]; n++)
        {
            for(int o = 0; o < nbrC[m]; o++)
            {               
                file.read(reinterpret_cast<char *>(&x0), sizeof(x0));
                tmpC.push_back(x0);
            }
            tmpL.push_back(tmpC);
        }
        dataT.push_back(tmpL);
        break;
    case 1:
        float x1;
        for(int n = 0; n < nbrL[m]; n++)
        {
            for(int o = 0; o < nbrC[m]; o++)
            {               
                file.read(reinterpret_cast<char *>(&x1), sizeof(x1));
                tmpC.push_back(x1);
            }
            tmpL.push_back(tmpC);
        }
        dataT.push_back(tmpL);
        break;
    }

在调用函数 m = 0 时,这意味着它是数据中两个表中的第一个。

但我不明白为什么数据读取开始有效,然后在几次读取后停止工作。 根据我使用的二进制文件,标题总是被正确读取,但读取的浮点数的数量会有所不同,即使至少读取了两个。

我尝试使用 seekg() 手动放置读取点,但效果完全一样。

如果您发现了什么或需要更多信息,感谢您的回答

【问题讨论】:

  • 在 Windows 上,您需要使用 "b" 标志打开文件以确保不会发生文本解释。
  • 哇,非常感谢,我确定我做到了,我今天早些时候一定已经改变了......对不起,那么长的帖子!我是堆栈溢出的新手,如何接受答案?
  • 应该有一个“接受”按钮。
  • 我是堆栈溢出的新手 -- 好吧,我为您实际进行合法、经过深思熟虑的二进制文件读/写而表扬。这里有很多与此相关的问题涉及将 STL 容器和std::strings 保存在二进制文件中,并想知道为什么程序无法正确读取/写入。
  • 值是大端还是小端?

标签: c++ binary readfile


【解决方案1】:

在 Windows 上,您需要使用 "b" 标志打开文件,以确保不会发生文本解释。文本模式发生了重大变化:

  1. \x0d\x0a 组合转换为 \x0a。 (或者 \x0d 可能会被完全删除,我忘了)。
  2. \x1a 被认为是文件结束和读取停止。

在尝试读取二进制数据时,这两种情况都将是致命的。二进制数据本质上是随机的,因此您有 1/65536 的机会满足第一个条件,有 1/256 的机会满足第二个条件!

大多数其他操作系统不区分二进制和文本模式,因此您不会在这些平台上遇到这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多