C++读取二进制文件
有一个二进制文件,二进制文件有个Head部分和Data部分。Head部分依次为:Identifier:3bypeIdentifier:1bypeData:1bypeFir...
有一个二进制文件,二进制文件有个Head部分和Data部分。
Head部分依次为:
Identifier:3 bype
Identifier:1 bype
Data:1 bype
FirstCycle: 2 bype
NumCycle: 2 bype
NumCluster: 4 bype
为了读取Head部分,我定义了一个结构体
struct head
{
char Identifier[3];
char Version;
char Data;
unsigned short int FirstCycle;
unsigned short int NumCycle;
unsigned int NumCluster;
};
所有的多字节的数字都是little endian的,所有我写了一个函数模版用于把little endian更正过来,如下:
//把Little-Endian 转换成 Bit-Endian
template <typename T>
T LittleToBig(T in)
{
T out;
char *p,*q;
p=(char *) &out;
q=(char *) ∈
q+=sizeof(in)-1;
for (int i=0;i<sizeof(in) ;i++ )
{
memcpy(p,q,1);
p++;
q--;
}
return out;
}
我要把Head部分读取出来,遇到了一个问题:我用ifstream 的read函数读取文件,在读取Identifier,Version,Data的时候没有什么问题,到后面的时候就文件指针有发生了变化。
Identifier[3] 读了前3个字节
Version 读了第4个字节
Data 读了第5个字节
FirstCycle读了第6,7个字节
NumCycle读了第9,10个字节
NumCluster读了第13,14,15,16个字节,我不明白为什么文件指针会发生变化
我的程序代码如下:
#include <iostream>
#include <fstream>
using namespace std;
struct head
{
char Identifier[3];
char Version;
char Data;
unsigned short int FirstCycle;
unsigned short int NumCycle;
unsigned int NumCluster;
char nouser[3];
};
//把Little-Endian 转换成 Bit-Endian
template <typename T>
T LittleToBig(T in)
{
T out;
char *p,*q;
p=(char *) &out;
q=(char *) ∈
q+=sizeof(in)-1;
for (int i=0;i<sizeof(in) ;i++ )
{
memcpy(p,q,1);
p++;
q--;
}
return out;
}
int main(int argc, char *argv[])
{
ifstream infile (argv[1],ios::binary);
if (! infile)
{
cerr << "open error!" << endl;
abort();
}
struct head Header;
infile.read((char *)&Header,13);
cout << "Identifier:" << Header.Identifier << endl;
cout << "Version:" << (int) Header.Version << endl;
cout << "Data:" << (int) Header.Data << endl;
cout << "FirstCycle:" << Header.FirstCycle << "\t" << (int)LittleToBig(Header.FirstCycle) << endl;
cout << "NumCycle:" << Header.NumCycle << "\t" << (int)LittleToBig(Header.NumCycle) << endl;
cout << "NumCluster:" << Header.NumCluster << "\t" << (int)LittleToBig(Header.NumCluster) << endl;
return 0;
}
程序的输出如下:
Identifier:CIF
Version:1
Data:2
FirstCycle:256 1
NumCycle:52736 206
NumCluster:0 0
各位帮我看看,为什么文件指针会发生变化呢? 展开
Head部分依次为:
Identifier:3 bype
Identifier:1 bype
Data:1 bype
FirstCycle: 2 bype
NumCycle: 2 bype
NumCluster: 4 bype
为了读取Head部分,我定义了一个结构体
struct head
{
char Identifier[3];
char Version;
char Data;
unsigned short int FirstCycle;
unsigned short int NumCycle;
unsigned int NumCluster;
};
所有的多字节的数字都是little endian的,所有我写了一个函数模版用于把little endian更正过来,如下:
//把Little-Endian 转换成 Bit-Endian
template <typename T>
T LittleToBig(T in)
{
T out;
char *p,*q;
p=(char *) &out;
q=(char *) ∈
q+=sizeof(in)-1;
for (int i=0;i<sizeof(in) ;i++ )
{
memcpy(p,q,1);
p++;
q--;
}
return out;
}
我要把Head部分读取出来,遇到了一个问题:我用ifstream 的read函数读取文件,在读取Identifier,Version,Data的时候没有什么问题,到后面的时候就文件指针有发生了变化。
Identifier[3] 读了前3个字节
Version 读了第4个字节
Data 读了第5个字节
FirstCycle读了第6,7个字节
NumCycle读了第9,10个字节
NumCluster读了第13,14,15,16个字节,我不明白为什么文件指针会发生变化
我的程序代码如下:
#include <iostream>
#include <fstream>
using namespace std;
struct head
{
char Identifier[3];
char Version;
char Data;
unsigned short int FirstCycle;
unsigned short int NumCycle;
unsigned int NumCluster;
char nouser[3];
};
//把Little-Endian 转换成 Bit-Endian
template <typename T>
T LittleToBig(T in)
{
T out;
char *p,*q;
p=(char *) &out;
q=(char *) ∈
q+=sizeof(in)-1;
for (int i=0;i<sizeof(in) ;i++ )
{
memcpy(p,q,1);
p++;
q--;
}
return out;
}
int main(int argc, char *argv[])
{
ifstream infile (argv[1],ios::binary);
if (! infile)
{
cerr << "open error!" << endl;
abort();
}
struct head Header;
infile.read((char *)&Header,13);
cout << "Identifier:" << Header.Identifier << endl;
cout << "Version:" << (int) Header.Version << endl;
cout << "Data:" << (int) Header.Data << endl;
cout << "FirstCycle:" << Header.FirstCycle << "\t" << (int)LittleToBig(Header.FirstCycle) << endl;
cout << "NumCycle:" << Header.NumCycle << "\t" << (int)LittleToBig(Header.NumCycle) << endl;
cout << "NumCluster:" << Header.NumCluster << "\t" << (int)LittleToBig(Header.NumCluster) << endl;
return 0;
}
程序的输出如下:
Identifier:CIF
Version:1
Data:2
FirstCycle:256 1
NumCycle:52736 206
NumCluster:0 0
各位帮我看看,为什么文件指针会发生变化呢? 展开
1个回答
展开全部
我想大概是c++编译器做的字对齐的原因,因为你的编译器是32位(我猜的,因为大多都是),每次能够读取4byte的数据,所以数据在内存中被以4字节为单位划分成了一个个小块,每次读取一个,为了读取速度,编译器会保证同一个数据尽量不横跨两个小块
例如你那个struct,你认为占用空间是多少呢,16吗,不其实是20,具体这么存的
char Identifier[3] 1 2 3
char Version 4
char Data; 5
unsigned short int FirstCycle; 6 7
8空着,如果不空着放numcycle的话,那么numcycle就会占用8 9 而横跨两个四字节小块了
unsigned short int NumCycle; 9 10
11 12 空着,原因同上
unsigned int NumCluster; 13 14 15 16
char nouser[3]; 17 18 19
20 空着
你读入的时候直接将struct指针转为字符串指针,读入的时候当然不会管哪些地方是空着的一律靠前填充,而输出的时候把它当作结构输出,因此空着的地方明明有数据却不会输出,看起来就像是文件指针变化一样,其实跟文件是没关系的
例如你那个struct,你认为占用空间是多少呢,16吗,不其实是20,具体这么存的
char Identifier[3] 1 2 3
char Version 4
char Data; 5
unsigned short int FirstCycle; 6 7
8空着,如果不空着放numcycle的话,那么numcycle就会占用8 9 而横跨两个四字节小块了
unsigned short int NumCycle; 9 10
11 12 空着,原因同上
unsigned int NumCluster; 13 14 15 16
char nouser[3]; 17 18 19
20 空着
你读入的时候直接将struct指针转为字符串指针,读入的时候当然不会管哪些地方是空着的一律靠前填充,而输出的时候把它当作结构输出,因此空着的地方明明有数据却不会输出,看起来就像是文件指针变化一样,其实跟文件是没关系的
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询