做课程设计.到结束阶段,文件操作遇到了一点问题. 帮我看看.新年快乐

Thorwein 2008-01-01 05:01:13

请教一个文件问题。
祝csdn的网友新年快乐。有个美好的2008。每个人经过努力都能实现自己心中的梦想。

问题是这样的。这几天在做课程设计。基本上已经完成。
在做文件的读取,和更新文件后遇到了问题。
这是我的测试程序


#include<fstream>
#include<iostream>
#include<string>
using namespace std;
class BaseData // 抽象类
{
public:

virtual int Getnumkey()const=0;
};

class SData:public BaseData // student data 学生数据对象
{
private:
string name; // 姓名
int numkey; // 编号
char sex; // 姓名 (男M 女G)
string address; // 地址
public:
SData(); // 默认构造函数
SData(SData & nsdata); // 赋值构造函数
SData(string nname,int nnumkey,char nsex,string naddress); // 构造函数
virtual int Getnumkey()const; // 返回数据成员numkey
string Getname()const; // 返回数据成员name
string Address()const; // 返回数据成员address
void Showsdata()const; // 显示学生信息
void Setdata();
};

SData::SData()
{
name="空";
numkey=-1;
sex='N';
string address="空";
}

SData::SData(SData &nsdata)
{
name=nsdata.name;
numkey=nsdata.numkey;
sex=nsdata.sex;
address=nsdata.address;
}

SData::SData(string nname,int nnumkey,char nsex,string naddress)
{
name=nname;
numkey=nnumkey;
sex=nsex;
address=naddress;
}

int SData::Getnumkey()const
{
return numkey;
}

string SData::Getname()const
{
return name;
}

string SData::Address()const
{
return address;
}

void SData::Setdata()
{
}

void SData::Showsdata()const
{
cout.width(3);
cout<<"name:"<<name;

cout.width(3);
cout<<numkey<<":";

cout.width(3);
cout<<sex<<":";

cout.width(3);
cout<<address<<":";
cout<<endl;
}

int main()
{
//------------------------------------------------
ofstream outfile("student.dat",ios::out|ios::binary); // 定义文件流对象,打开磁盘"student.data
if(! outfile)
{
cerr<<"open error!"<<endl;
exit(1);
}
SData s1=SData ("杨过",1,'M',"古墓");
SData s2=SData ("令狐冲",2,'M',"华山");
SData s3=SData ("萧十一郎",3,'M',"流浪");
SData s4=SData ("黄老邪",3,'M',"桃花岛");

SData s5=SData ("欧阳丰",4,'M',"西域");
SData s6=SData ("洪七公",5,'M',"流浪");
SData s7=SData ("段王爷",6,'M',"和尚庙");
SData s8=SData ("黄老邪1",7,'M',"桃花岛");
SData s9=SData ("黄老邪2",8,'M',"桃花岛");
SData s10=SData ("黄老邪3",9,'M',"桃花岛");

outfile.write((char *)&s1,sizeof(s1));
outfile.write((char *)&s2,sizeof(s2));
outfile.write((char *)&s3,sizeof(s3));
outfile.write((char *)&s4,sizeof(s4));
outfile.write((char *)&s5,sizeof(s5));
outfile.write((char *)&s6,sizeof(s6));
outfile.write((char *)&s7,sizeof(s7));
outfile.write((char *)&s8,sizeof(s8));
outfile.write((char *)&s9,sizeof(s9));
outfile.write((char *)&s10,sizeof(s10));
outfile.close();

//------------------------------------------------
// 第一次运行程序,在目录下生成student.dat文件。 第二次运行程序,我把上面这段注释掉。
//利用下面这段来程序来把文件数据读入内存,在显示出来。但是显示出来的东西怪怪的。是乱码。
// 翻开了一些书,还是摸不着头发,发现不了问题出在哪儿?


ifstream infile("student.dat",ios::binary);
if(!infile)
{
cerr<<"open error!"<<endl;
abort();
}

SData t1;
SData t2;
SData t3;
SData t4;
SData t5;
SData t6;
SData t7;
SData t8;
SData t9;
SData t10;

infile.read((char *)&t1,sizeof(t1));
infile.read((char *)&t2,sizeof(t2));
infile.read((char *)&t3,sizeof(t3));
infile.read((char *)&t4,sizeof(t4));
infile.read((char *)&t5,sizeof(t5));
infile.read((char *)&t6,sizeof(t6));
infile.read((char *)&t7,sizeof(t7));
infile.read((char *)&t8,sizeof(t8));
infile.read((char *)&t9,sizeof(t9));
infile.read((char *)&t10,sizeof(t10));

t1.Showsdata();
t2.Showsdata();
t3.Showsdata();
t4.Showsdata();
t5.Showsdata();
t6.Showsdata();
t7.Showsdata();
t8.Showsdata();
t9.Showsdata();
t10.Showsdata();
//cout<<sizeof(t1)<<"对象的数据内存"<<endl;
//cout<<2*sizeof(string)+sizeof(int)+sizeof(char)<<endl;
//cout<<sizeof(A);

infile.close();
return 0;
}

...全文
195 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Thorwein 2008-01-03
  • 打赏
  • 举报
回复
经过 几天奋战.终于把课程设计搞定了. 自己还是挺满意的.哈 :)
给分.
特别谢谢dizuo. ltc_mouse 两位的热心解答
lin_style 2008-01-02
  • 打赏
  • 举报
回复
建议楼主基类不要这么设置,没什么扩展性。关联度太高了

Thorwein 2008-01-02
  • 打赏
  • 举报
回复
-> lin_style
谢谢你的解答.
能否 说详细点.
?
不能完全领悟你的意思. 谢谢
JohhGan 2008-01-02
  • 打赏
  • 举报
回复
ding
ltc_mouse 2008-01-01
  • 打赏
  • 举报
回复
而为什么,把写文件和读文件在一个main()里面就可以正确的读出来,显示出来.
==================================================
都在main函数时,s1~s10变量是有效的,对应的内存没有被释放——这些内存保存有string内容;而读出的内容,包含了这些未释放的内存地址,可以从中得到正确的内容。
dizuo兄弟可以第二次运行时正确的读出内容,让我挺吃惊的,^_^
ryfdizuo 2008-01-01
  • 打赏
  • 举报
回复
没什么的...
QQ:546952720
MSN:dizuo@live.cn

Thorwein 2008-01-01
  • 打赏
  • 举报
回复
谢谢你了. DIZUO.
想要一个你的联系方式 可以不?

恩.我等等再试一试看看.现在 在 调整一些 I/O 输出格式.
基本上已经完成了。就差这个文件操作了。还有一个实验报告.
ryfdizuo 2008-01-01
  • 打赏
  • 举报
回复

写的不错的啊,思路很清晰的嘛,加油啊, ^_^
改成流操作较容易的,
可以在SData类里面重载operator<<,
ostream& operator<<(ostream& out, SData& temp)
{
out << temp.name << " ";
out << temp.numkey << " ";
out << temp.sex << " ";
out << temp.address << endl;
return out;
} 方便输出ShowData,也方便写到文件中去,
读取的时候直接:
inFile>>tem.name>>tem.numkey>>tem.sex>>tem.address;
注意顺序就可以了,
Thorwein 2008-01-01
  • 打赏
  • 举报
回复
>dizuo

代码大概写了600~700行. 而这个是基础数据,要改动的话 真的是很大了。
你机子上不会?? 我找另外一台机子看看.

两个相关函数

bool Loadfile(SMgrsys &smgrsys)
{
cout<<"读取数据中,请您稍等...:)"<<endl;
ifstream infile("student.dat",ios::binary|ios::in);
if(!infile)
{
cout<<"没有数据文件!!!"<<endl;
return false;
}
while(!infile.eof())
{
SData data; // 定义数据对象
infile.read((char *)(&data),sizeof(data));
data.Showsdata();
Snode *pnode =new Snode;
pnode->Inputsdata(&data); // 数据域内容生成
(smgrsys.Getplist())->Insert(&data); // 将结点加入链表。
}


infile.close();
return true;
}



bool Updatefile(SMgrsys &smgrsys)
{
cout<<"将你的更新信息,存储中...."<<endl;
ofstream outfile("student.dat",ios::binary|ios::in);
if(!outfile)
{
cout<<"存储失败/007!!!"<<endl;
return false;
}
Snode * current;
current=(smgrsys.Getplist())->Getpfirst();
while(NULL!=current)
{
outfile.write((char*)current,sizeof(Snode));
current=(current->Getnext());
}
return true;
}


除了我上面的问题外.还有什么好的意见吗?
我写的是学生信息管理系统.
atongmu1023 2008-01-01
  • 打赏
  • 举报
回复
还是有流操作吧。
ryfdizuo 2008-01-01
  • 打赏
  • 举报
回复

我的机子上是没有问题的啊,如果正如四楼兄弟所说的话,
你可以将string name, string address;
换成:char name[10], char address[10];试一下,这样子改动较大的,

要是还不行的话,就用<<流操作吧, 那样是肯定可以的,

Thorwein 2008-01-01
  • 打赏
  • 举报
回复
>dizuo
谢谢你的回答,新年快乐.

但是问题还没有解决.呵呵.

你在3楼的回答. 我测试过了,结果和我的代码一样.

我的代码:
写文件,和读文件 都在main()中时,读取文件后,是可以正确的显示出对象信息的.
当把写文件注释掉时(因为第一次运行已经生成了student.dat文件),直接读文件.显示的时候就不正确了.
显示出了一大堆的"屯"字.

我读文件 和写文件是分别打算 用在两个函数里面的.LoadFlie() // 读文件 updateFlie() // 写文件.
从文件中 加载学生信息. 经过更改后 把更新后的学生信息.在存入文件中.. 用到的数据结果 是 链表.

还是搞不懂 为什么我的测试程序 哪儿出了问题. 而为什么. 把写文件 和读文件在一个 main()里面 就可以正确的读出来,显示出来.
ryfdizuo 2008-01-01
  • 打赏
  • 举报
回复

用空格分开啊,每条记录占一行;
读取
直接getline(), 而后分割字符串,
或者:
逐个string的处理,把姓名,学号,性别,地址全部以string类型来处理,反正每行的string个数是确定的:4
ifstream inFile("hotel.txt");
istream_iterator<string> bg(inFile);
istream_iterator<string> ed;
for (bg; bg!=ed; ++bg)
{
...
}

Thorwein 2008-01-01
  • 打赏
  • 举报
回复
ltc_mouse
野地芳菲
----
谢谢你的解答。
重载<<运算,用流式操作写文件。 但是用>>读文件 准确的把 一个对象读出来 不是很有难度吗?
ltc_mouse 2008-01-01
  • 打赏
  • 举报
回复
类SData中,有另一个类string address,在实现时可能是动态分配内存;因而outfile.write((char *)&s1,sizeof(s1));保存的只是address字符串的首地址;去掉部分代码再次运行程序时,保存的那些地址是未初始化的,因而显示乱码

建议重载<<运算符,用流式操作写文件。
ryfdizuo 2008-01-01
  • 打赏
  • 举报
回复

什么问题,读取文件时候这样子,没有问题的啊,
int main()
{
ifstream infile("student.dat",ios::binary);
if(!infile)
{
cerr<<"open error!"<<endl;
abort();
}
SData test;
while ( !infile.eof() )
{
infile.read((char *)&test,sizeof(test));
test.Showsdata();
}

infile.close();
return 0;
}

qiannv 2008-01-01
  • 打赏
  • 举报
回复
lu guo he he !
qiannv 2008-01-01
  • 打赏
  • 举报
回复
lu guo he he !

64,642

社区成员

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

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