
问题描述:
#include <iostream>
#include <string>
#include <fstream>
using namespace std
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((char * )&str1,sizeof(string))
outfile.write((char * )&str2,sizeof(string))
outfile.close()
ifstream infile("temp.dat",ios::binary)
if (! infile)
{
cerr <<"Error ! " <<endl
return 0
}
infile.read((char * )&str1,sizeof(string))
infile.read((char * )&str2,sizeof(string))
cout <<str1 <<endl
cout <<str2 <<endl
return 1
}
如果我就这样执行的话,str1和str2能保存到文件,而且能够成功读取并显示。
但如果我把“保存”的那一段代码删掉,读取就会失败,显示乱码。怎么回事?怎么解决?(不要复制一大堆东西过来,谢谢。)
解析:
不是以上两位说的原因,因为string类实际上是对char*的封装,你用write那样写其实只是把对应的指针也就是内存地址写进文件了,在执行期,读出的是指针,这时内存中的字符串还在,可以正确显示,你把"保存"的那段删了,实际上刚才在内存中的东西已经没有了,输出的也就是乱码了,这就是你错的原因,我改了下你的程序:
#include <iostream>
#include <string>
#include <fstream>
using namespace std
int main()
{
string str1
string str2
int len1,len2
cin >>str1
cin >>str2
ofstream outfile("temp.txt",ios::binary)
if(! outfile)
{
cerr <<"Error ! " <<endl
return 0
}
len1=str1.length()
len2=str2.length()
outfile.write((char*)str1.c_str(),len1)
outfile.write(" ",sizeof(char))
outfile.write((char*)str2.c_str(),len2)
outfile.write(" ",sizeof(char))
outfile.close()
ifstream infile("temp.txt",ios::binary)
if (! infile)
{
cerr <<"Error ! " <<endl
return 0
}
infile>>str1>>str2
cout <<str1 <<endl
cout <<str2 <<endl
return 1
}
改的地方一眼就看出来了,就不说了,其实我用的方法很简单也有缺陷,不过这只是一个演示,如果你明白我刚才说的那些,知道了原理,你很容易改成任意你想要的效果
你保存的时候应该这样保存: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
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)