【问题标题】:Building 32bit Float from 4 Bytes [Binary File I/O] in C++在 C++ 中从 4 字节 [二进制文件 I/O] 构建 32 位浮点数
【发布时间】:2014-10-10 22:08:27
【问题描述】:

我确定这一定是一个常见问题,但似乎找不到等效的问题*或示例。

我有一个二进制文件,它是一系列 4 字节浮点数。我正在读入一个按文件长度(除以我的浮点数)大小的向量。我使用了来自another post 的 bytesToFloat 方法。打印出数据时,我的代码为所有数据点返回相同的值。怎么了?

*如果我错过了,请向管理员道歉。

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

typedef unsigned char uchar;

float bytesToFloat(uchar b0, uchar b1, uchar b2, uchar b3);

int main()
{
int i,j;
char u[4];
// Open  file
ifstream file;
file.open("file.dat");
// Find file size in bytes
file.seekg(0,ios::end);
double size = 0;
size = file.tellg();
file.seekg(0,ios::beg);

vector<float> data;
data.resize(size/4);
i=0;
while(i<size/4)
{
    j=0;
    while(j<4)
    {
        file.read(&u[j],1);
        j++;
    }
    data[i] = bytesToFloat(u[0],u[1],u[2],u[3]);

    cout << data[i]<< endl;
    i++;
}

// End program
file.close();
return 0;
}

float bytesToFloat(uchar b0, uchar b1, uchar b2, uchar b3)
{
float output;

*((uchar*)(&output) + 3) = b0;
*((uchar*)(&output) + 2) = b1;
*((uchar*)(&output) + 1) = b2;
*((uchar*)(&output) + 0) = b3;

return output;
}

【问题讨论】:

  • 如果你放弃所有这些循环,只执行file.read(&amp;data[0], size);(在resize 调用之后)会发生什么?将size 设为整数。另外,你怎么知道你的文件实际上包含相同值的副本?
  • 我之前尝试了 file.read 方法,它只输出十六进制值而不是浮点数本身。这就是为什么我尝试从其各个字节重新构造浮点数的原因。我在 Visual Studio 中打开文件,十六进制值不同。它也是从我编写的另一段代码中随机生成的,该代码生成了一系列随机浮点数(我已经检查了该程序的输出)。
  • 你是什么意思,“它只输出”? read 不输出任何内容。
  • 我将使用file.read 获得的buffer 中的值发送到cout。它打印十六进制值而不是我希望它存储的浮点数。
  • 您显示的代码中没有名为 buffer 的变量。

标签: visual-c++ file-io binaryfiles


【解决方案1】:

因此,通过一些努力和 Igor 的评论,我能够解决问题。以下函数将所有内容读入缓冲区向量。

vector<char> buffer;

void fill() {
string filename = "";
cout << "Please enter a filename:\n>";
getline(cin, filename);

ifstream file(filename.c_str());

if (file) {
    file.seekg(0,std::ios::end);
    streampos length = file.tellg();
    cout<< length << endl;
    file.seekg(0,std::ios::beg);
    file.seekg(540,'\0');

    length-=540;
    buffer.resize(length);
    file.read(&buffer[0],length);
}
}

然后我在循环中调用 bytesToFloat。 bytesToFloat 的字节序不正确,因此现在已反转,它输出与我的原始文件相同的值(我让我的随机文件生成器输出纯文本版本以进行比较)。

【讨论】:

  • 您的意思是要跳过文件的前 540 个字节吗?这就是file.seekg(540,'\0'); 所做的。无论如何,我很确定 file.read((char*)&amp;data[0], length) 会产生相同的效果(datavector&lt;float&gt;,适当调整大小),而不需要 bytesToFloat
  • 我在文件中跳过了一个固定字节长度的标题(为了简单起见,我之前没有提到过)。我尝试使用您之前建议的方法,但无法正常工作(我一直收到与转换为 char 相关的错误)。
  • 计算length 的方式不考虑这个固定的标题。是的,我忘记了在我最初的建议中需要转换为char*。有了演员表,你应该可以直接读入data
  • 我已经在我的代码中修复了length,我从中删除了跳过。我将在上面编辑我的回复。
猜你喜欢
  • 1970-01-01
  • 2011-04-28
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多