二进制文件中string类写入读出疑问

striveforit 2009-08-17 03:12:54
为什么不能从E中读出e.num和e.length的值呢?

运行结果:
input key: annoy
从文件中读到的 -858993460 -858993460 annoy
麻烦啊
Press any key to continue

#include<fstream.h>
#include<iostream>
#include<string>
using std::string;

#define keylenth 10

//记录关键字类型
typedef char KeyType[keylenth];


struct ElemType{
KeyType key; //关键字域
string content; //内容域
long length; //整个记录长度
int num; //记录号
};


void main()
{
ElemType e;
cout<<"input key: ";
cin>>e.key ;
e.content="麻烦啊";
e.num =123;
//18=sizeof(e.num)+sizeof(e.key)+sizeof(e.length );
e.length=e.content.size()+1+18;
fstream ofs("1.dat",ios::in|ios::out|ios::binary);
if(!ofs){cout<<"不能打开"<<endl;exit(1);}
ofs.seekp(0,ios::end); //指针移到文件尾
long t=ofs.tellp(); //写入e前的指针位置
ofs.write((char*)&e,e.length);//写入e, 这样子对不对?????

ElemType E;
ofs.seekp(t,ios::beg);//指针定位到写入e前的地址
ofs.read((char*)&E,e.length);
cout<<"从文件中读到的 "<<E.num<<" "<<E.length<<" "<<E.key<<endl;
std::cout<<(E.content);
cout<<endl;
}
...全文
300 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
striveforit 2009-08-17
  • 打赏
  • 举报
回复
谢谢mstlq~~
原以为这帖子要沉了,谁知还有意外惊喜啊~~

综合大家的教诲,我这样写的,测试结果还行
y.content.reserve(e.length);//申请空间
ifs.read((char*)&y,size);
cout<<y.num<<" "<<y.key<<" "<<y.length<<endl;
ifs.read((char*)y.content.c_str(),y.length);
std::cout<<"该记录内容为:"<<y.content<<std::endl;
y.length其实就是e.content.size()+1

谢谢大家~~现在对string类有一点点自己的理解,就不清楚对不对。
不知道大家对于了解string类,有什么推荐的书刊或别的了解途径吗?
先不那么快结贴,期待大家的指点~~
mstlq 2009-08-17
  • 打赏
  • 举报
回复
楼上漏了一句buffer[len]='\0',请自行补全……
mstlq 2009-08-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 striveforit 的回复:]
因为要实现不定长数组,所以想用string类
    ofs.write((char*)&e,18);
    ofs.write(e.content.c_str(),e.content.size()+1)
这样子写入,不知道要怎么读出
[/Quote]

请问楼主的18已经考虑字节对齐问题了吗?
我先忽略此问题……
大体思路……

写入
ofs.write((char*)&e,18);
int len=e.content.size();
ofs.write((char*)&len,sizeof(len));
ofs.write(e.content.c_str(),e.content.size())

ifs.read((char*)&e,18);
int len;
ifs.read((char*)&len,sizeof(len));
char *buffer = new char[len+1];
ifs.read((char*)&buffer,len);
e.content=buffer;




striveforit 2009-08-17
  • 打赏
  • 举报
回复
因为要实现不定长数组,所以想用string类
ofs.write((char*)&e,18);
ofs.write(e.content.c_str(),e.content.size()+1)
这样子写入,不知道要怎么读出
The_facE 2009-08-17
  • 打赏
  • 举报
回复
最好的办法还是定义TCHAR数组(或者char 数组),这样读取的长度也比较一致。

不过结构体中保存一下长度也不失为好的办法。不过结构体中有了string类成员就无法直接把结构体作为存储单元了,最好一个一个数据项读取,一个一个保存。

做文件操作的时候,如果知道字符串的最大长度,还是用数组好一些,保存数据单元只需要直接保存一个结构体就行了。
striveforit 2009-08-17
  • 打赏
  • 举报
回复
struct ElemType{
KeyType key; //关键字域
long length; //整个记录长度
int num; //记录号
string content; //内容域

};
content放最后
striveforit 2009-08-17
  • 打赏
  • 举报
回复
改为这样对不对?
ofs.write((char*)&e,18);
ofs.write(e.content.c_str(),e.content.size()+1);
//长度应该是字符串的长度(包括结束符'\0')


ofs.read((char*)&E,(18+e.content.size()+1));
The_facE 2009-08-17
  • 打赏
  • 举报
回复
string::c_str();

使用它转换成const char *再写入文件。
striveforit 2009-08-17
  • 打赏
  • 举报
回复
请问对应ElemType这种包含string类的类型,怎么把记录写入二进制文件啊
mstlq 2009-08-17
  • 打赏
  • 举报
回复
string里面有指针……
把指针写到文件里是没有意义的……
HengStar 2009-08-17
  • 打赏
  • 举报
回复
struct ElemType{
KeyType key; //关键字域
string content; //内容域
long length; //整个记录长度
int num; //记录号
};
你忘了还有content的长度没算进来吧,e.content.size()是它包含的字符串长度(默认是0)
如果你要得到string本身结构的长度应该用sizeof(string)或sizeof(e.content)

e.length=e.content.size()+1+18;
改成
e.length=sizeof(string)+1+18;
试试

65,184

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧