gpt4 book ai didi

c++ - 尝试读取 4 字节无符号整数的二进制文件并转换为伏特

转载 作者:行者123 更新时间:2023-11-28 03:02:07 26 4
gpt4 key购买 nike

我有一些实验记录的数据,保存为二进制文件。记录了多个电压样本,我被告知每个样本都是 0 到 0xFFFFFF 范围内的 4 字节无符号整数(unsigned integer)。因此,我尝试读取 C++ 中的二进制文件,执行将二进制数据转换为伏特的计算,并将这些值写入 .csv 文件(我可以从中将其导入我的分析软件)。

问题:我尝试使用 fread() 将二进制文件放入名为“缓冲区”的数组中。它编译时没有给我一个错误,但是数组的大小在某处发生了变化,变成了原来大小的四倍,程序本身崩溃了。它将相同的值重复写入 .csv 文件。我是否正确使用了 fread()?

我尝试了什么(在 Notepad++ 中,使用 Borland 编译器):

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <fstream>
#include <iostream>
#include <cstdio>

using namespace std;

int main () {

FILE * pFile;
int buffer[30000];

pFile = fopen ("00001001.e01", "rb");

fread(buffer, 4, 30000, pFile); // Copy the file into the buffer:

int buffsize = sizeof(buffer);
cout << buffsize; //How big is the buffer? It's 120000 now (error)

//Open .csv file
ofstream outFile;
outFile.open("test.csv");

/* Loop to calculate voltage V[i] to V[n]*/
int volts[30000];

for (int i=0; i < sizeof(buffer); i++)
{
volts[i] = 1.6 * (buffer[i] - 0x7FFFFF) / 0x7FFFFF;
outFile << volts[i] << ";" << endl; /* To write each calculated value to the .csv file.*/
}; //Error - now writes 30000 values that are all same value - "817'

// Terminate
fclose (pFile);
free (buffer);
outFile.close();
return 0;
}

最佳答案

  • sizeof对您读取的数据一无所知,它只是告诉您缓冲区的大小(以字节为单位),即 30000*sizeof(int) ,在您的情况下(32 位 int)是 120000 字节;
  • sizeof告诉数组的字节大小(而不是元素的数量),你的 for 的条件。错了,应该是i<totElems , 其中totElems包含元素总数;
  • 缓冲区的类型应该是unsigned int或者,更好的类型是 uint32_t (unsigned int 不保证是 4 字节);
  • 如果你想在volts中存储一个浮点值, 你必须制作 float 类型的数组或 double ;但实际上,您不需要 volts数组 - 您可以将计算的输出写入 outFile , 而不是将其存储在任何地方;
  • endl将通过执行不必要的缓冲区刷新来无用地减慢您的程序;就做<<'\n' ;
  • free(buffer)是完全错误的; free仅用于使用 malloc 动态分配的内存& friends,一个像buffer这样的本地数组或 volts在函数结束时自动释放;
  • 你混合使用了 C(fopen & co.)和 C++(fstream & co.)的东西(另外,你还包括了几个实际上没有使用的 POSIX 头文件);避免这种情况,用 C 或 C++ 编写。

这一切如果事先知道元素个数是30000;如果不是这种情况,您有不同的方法来解决这个问题:

  • 确定元素的数量(用 fseek 到文件末尾,用 ftell 得到位置,除以元素大小,回到文件开头),为它们分配足够的内存, 像你一样阅读它们并像你已经做的那样继续;通常是个坏主意,你会白白浪费大量内存;
  • 另一方面,最简单的方法实际上是去掉数组;从输入文件中读取单个值,计算转换后的值,将其写入输出文件;继续下一个;当没有更多数据时终止循环(feof(pFile) 返回非零值);
  • 您可能会通过大块读取数据来提高性能,但是,除非您处理的是非常大的文件,否则如果您对 C 和 C++ 的了解有限,我会避免使用它。

所以,我的建议是:坚持使用第二种方法。

总结起来,你可能会得到这样的结果:

#include <fstream>
#include <stdint.h>

int main()
{
std::ifstream is("inputfile.dat", std::ios::binary);
std::ofstream os("output.csv");
uint32_t i;
while(is.read((char *)&i, sizeof(i)))
os<<1.6*(i-0x7fffff)/0x7fffff<<";\n";
return 0;
}

备注:

  • 如果你的编译器不提供uint32_t你应该删除 <stdint.h>行和使用unsigned int而不是 uint32_t ,也许会添加一个 assert(sizeof(unsigned int)==4) ;
  • 如果你必须处理一个以上的文件,你可能应该制作输入和输出文件的命令行参数;使用 argv为此。

关于c++ - 尝试读取 4 字节无符号整数的二进制文件并转换为伏特,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20509133/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com