二进制文件的二进制文件的储存方式

二进制文件的二进制文件的储存方式,第1张

列举一个二进制文件如下:

00000000h:0F 01 00 00 0F 03 00 00 12 53 21 45 58 62 35 34.........S!EXb54

00000010h:41 42 43 44 45 46 47 48 49 47 4B 4C 4D 4E 4F 50ABCDEFGHIGKLMNOP

这里列出的是在 UltraEdit(UE) 里看到的东西。其实只有红色部分是文件内容。前面的是 UE 加入的行号。后面的是 UE 尝试解释为字符型的参考。这个文件一共有 32 字节长。显示为两列,每列 16 个字节。实际上,这仅仅是 UE 的显示而已。真实的文件并不分行。仅仅知道这个文件的内容,如果我们没有任何说明的话,是不能看出任何有用信息的。下面我规定一下说明:我们认为,前 4 个字节是一个 4 字节的整型数据(0F 01 00 00 十六进制:10Fh 十进制:271)。这 4 个字节之后的 4 个字节是另一个 4 字节的整型数据(0F 03 00 00 十六进制:30Fh 十进制:783)。其后的 4 个字节(12 53 21 45 )表示一个 4 字节的实型数据:2.5811919E+3。再其后的 4 个字节(58 62 35 34)表示另一个 4 字节的实行数据:1.6892716E-7。而只后的 16 个字节(41 42 43 44 45 46 47 48 49 47 4B 4C 4D 4E 4F 50)我们认为是 16 个字节的字符串(ABCDEFGHIGKLMNOP)实际上,二进制文件只是储存数据,并不写明数据类型,比如上面的第 9 字节到第 16 字节(12 53 21 45 58 62 35 34),我们刚才认为是 2 个 4 字节的实型,其实也可以认为是 8 个字节的字符型( S!EXb54)。而后面的 16 个字节的字符串(ABCDEFGHIGKLMNOP),我们也可以认为是 2 个 8 字节的整型,或者 4 个 4 字节的整型,甚至 2 个 8 字节的实型,4 个 4 字节的实型,等等等等。因此,面对一个二进制文件,我们不能准确地知道它的含义,我们需要他的数据储存方式的说明。这个说明告诉我们第几个字节到第几个字节是什么类型的数据,储存的数据是什么含义。否则的话,我们只能猜测,或者无能为力。

文件有两种存放方式:文本方式,二进制方式. FILE *fp=fopen("1.txt","w")这是以文本方式写文件. FILE *fp=fopen("1.txt","r")这是以文本方式读文件. FILE *fp=fopen("1.dat","wb")这是以二进制方式写文件. FILE *fp=fopen("1.dat","rb")这是以二进制方式读文件.

应该这样保存:

int main()

{

string str1

string str2

cin >>str1

cin >>str2

ofstream outfile("temp.dat",ios::binary)

if(! outfile)

{

cerr <<"Error ! " <<endl

return 0

}

outfile.write(str1.c_str(),str1.size()+1)

/*你原来写成(char * )&str1,这样往文件里写入的东西其实是str1这个类的数据(包括了指向实际字符串的指针),而不是字符串。因为string类的字符串是用new在堆上分配的,string类本身只包含字符串的指针,用c_str()这个成员函数可以获得这个指针,你可以看一下string类的源码。

改成这样以后,写入文件里的就是实际的字符串了。

写入的长度应该是字符串的长度(包括结束符'\0')*/

outfile.write(str2.c_str(),str2.size()+1)

outfile.close()

return 1

}

读取的时候这样读取:

int main()

{

string str1

str1.reserve(100)/*为str1申请100个字符的空间,如果不申请的话c_str()返回的是空指针,也就是没有空间。假设你上次存的两个字符串长度不超过100。*/

ifstream infile("temp.dat",ios::binary)

if (! infile)

{

cerr <<"Error ! " <<endl

return 0

}

infile.read((char * )str1.c_str(),100)/*这儿由于不知道你上次写入文件的两个字符串的长度,只能把文件里的内容都读出来再根据'\0'来分析出两个字符串。*/

cout <<str1 <<endl//输出第一个字符串

cout <<(char*)(str1.c_str() + strlen(str1.c_str())+1) <<endl//输出第二个字符串

return 1

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/11533506.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存