读取 C++ 行中的不同数据类型
read different data types in line c++
我从c ++开始,我需要读取一个二进制文件。
我知道文件的结构,即每个文件行由以下部分组成:
'double';'int8';'float32';'float32';'float32';'float32';'float32';'float32';'int8';'float32';'float32';'float32';'float32';'int8';'float32'
或以字节数表示:
8 1 4 4 4 4 4 4 1 4 4 4 4 1 4
我做了一些代码,但太过时了...这是代码:
void test1 () {
const char *filePath = "C:20110527_phantom19.elm2";
double *doub;
int *in;
float *fl;
FILE *file = NULL;
unsigned char buffer;
if ((file = fopen(filePath, "rb")) == NULL)
cout << "Could not open specified file" << endl;
else
cout << "File opened successfully" << endl;
// Get the size of the file in bytes
long fileSize = getFileSize(file);
cout << "Tamanho do ficheiro: " << fileSize;
cout << "n";
// Allocate space in the buffer for the whole file
doub = new double[1];
in = new int[1];
fl = new float[1];
// Read the file in to the buffer
//fread(fileBuf, fileSize, 1, file);
//fscanf(file, "%g %d %g", doub[0],in[0],fl[0]);
fread(doub, 8, 1, file);
//cout << doub[0]<< " ";
fseek (file ,8, SEEK_SET);
fread(&buffer,1,1,file);
//printf("%d ",buffer);
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(&buffer,1,1,file);
//printf("%d ",buffer);
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(fl,4,1,file);
//cout << fl[0]<< " ";
fread(&buffer,1,1,file);
//printf("%d ",buffer);
fread(fl,4,1,file);
//cout << fl[0]<< "n";
cin.get();
//delete[]fileBuf;
fclose(file);
}
如何将其更改为有效的方法?
当您可以使用自定义格式轻松读取整个结构并自动填充正确的值时,有什么问题?
struct MyDataFormat {
double d;
int8 i1;
float32 f[6];
..
};
MyDataFormat buffer;
fread(&buffer, sizeof(MyDataFormat), 1, file);
如果每一行的格式相同,我可能会一次将一行读入缓冲区,然后有一个函数将该缓冲区拉成单独的元素 - 更容易理解,更容易测试,适用于更大的文件,并且可能更有效率地执行更少的读取。
除了文件的"结构",我们还需要知道格式所涉及的数据类型,以及"行"的含义(如果格式)不是文本格式。 但是,一般来说,您将 1) 必须阅读适当大小的块,然后从中提取每个值,根据指定的格式。 对于整数值,这是公平的使用移位轻松提取无符号整数值;对于int8
, 在事实上,你只需要读取字节。 对于大多数机器来说,只是铸造将无符号整数转换为相应大小的有符号类型将工作,尽管这显然不能保证;如果unsigned char
大于 CHAR_MAX
,您必须将其缩小才能获得
适当的值:类似于-(UCHAR_MAX+1 - value)
应该执行技巧(对于char
- 对于较大的类型,您还必须担心UINT_MAX+1
会溢出的事实)。
如果外部格式是IEEE,那也是你的机器使用(Windows和Unix机器的常见情况,但很少如此对于大型机),则可以读取无符号的 4 或 8 字节整数(再次,使用移位),然后键入双关语,例如:
uint64_t
get64BitUInt( char const* buffer )
{
return reinterpret_cast<double>(
((buffer[0] << 52) & 0xFF)
| ((buffer[1] << 48) & 0xFF)
| ((buffer[2] << 40) & 0xFF)
| ((buffer[3] << 32) & 0xFF)
| ((buffer[4] << 24) & 0xFF)
| ((buffer[5] << 16) & 0xFF)
| ((buffer[6] << 8) & 0xFF)
| ((buffer[7] ) & 0xFF) );
}
double
getDouble( char const* buffer )
{
uint64_t retval = get64BitUInt( buffer );
return *reinterpret_cast<double*>( &retval );
}
(这对应于通常的网络字节顺序。 如果您的二进制格式使用另一种约定,您必须对其进行调整。 而 reinterpret_cast
取决于实现定义的行为;你可以必须将其重写为:
double
getDouble( char const* buffer )
{
union
{
double d;
uint64_t i;
} results;
results.i = get64BitUInt( buffer );
return results.d;
}
. 甚至可以使用 memcpy
从uint64_t
复制到double
。
如果您的机器不使用 IEEE 浮点数,并且外部格式是 IEEE,您必须将 8 字节的单词作为 8 字节的无符号int ( unsigned long long
),然后提取符号、指数和尾数根据IEEE格式;如下所示:
double
getDouble( char const* buffer )
{
uint64_t tmp( get64BitUInt( buffer );
double f = 0.0 ;
if ( (tmp & 0x7FFFFFFFFFFFFFFF) != 0 ) {
f = ldexp( ((tmp & 0x000FFFFFFFFFFFFF) | 0x0010000000000000),
(int)((tmp & 0x7FF0000000000000) >> 52) - 1022 - 53 ) ;
}
if ( (tmp & 0x8000000000000000) != 0 ) {
f = -f ;
}
return f;
}
但是,在您确定需要它之前不要这样做。
- 防止主数据类型C++的隐式转换
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在C++中打印指向不同基元数据类型的指针的内存地址
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何计算数据类型的范围,例如int
- C++中数据类型修饰符的顺序
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 特定数据类型的模板类
- 具有多个模板的模板函数,用于特定数据类型(如字符串)?
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 如何获取C++字符数据类型的地址
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 构造智能点数据类型以及普通数据类型的通用方法
- 如何使映射键具有两种不同的数据类型?
- 数据类型"struct seq<0, 1, 2>{}"含义是什么?
- 如何在不破坏现有应用程序的情况下更改 API 中 stl 容器的数据类型?
- Static_cast转换为错误的数据类型,但结果仍然正确?
- 使用 Boost.Spirit 解析具有混合数据类型的 OBJ 文件?