二进制文件的读取问题

Aegwynn_Wei 2017-05-14 04:30:03
程序目的为了实现建立类对象是在构造函数中打开二进制文件把内容读取到对象中,析构对象时把对象的内容再存回去
但是现在出现了读不到二进制文件尾的问题,进入了死循环,请问哪里有问题
代码如下

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <conio.h>
using namespace std;


class Student
{
private:
string m_name;
int m_age;
double m_mark;
string m_address;
string m_number;
public:
Student(string name = "#", int age = 0, double mark = 100, string add = "#", string number = "#");
Student(Student &std)
{
m_name = std.m_name;
m_age = std.m_age;
m_mark = std.m_mark;
m_address = std.m_address;
m_number = std.m_number;
}
void FileRead(ofstream &file) const;
void FileWrite(ifstream &file) const;
friend ostream &operator<<(ostream &dist, Student &std);
friend istream &operator >> (istream &sour, Student &std);
bool operator>(Student &std);
bool operator==(Student &std);
};

Student::Student(string name , int age , double mark , string add , string number)
{
m_name = name;
m_age = age;
m_mark = mark;
m_address = add;
m_number = number;
}
bool Student::operator>(Student &std)
{
return m_mark > std.m_mark;
}

bool Student::operator==(Student &std)
{
return m_mark == std.m_mark;
}


ostream &operator<<(ostream &dist, Student &std)
{

cout << "学生姓名:" << '\t' << std.m_name << endl;
cout << "学生年龄:" << '\t' << std.m_age << endl;
cout << "学生成绩:" << '\t' << std.m_mark << endl;
cout << "学生住址:" << '\t' << std.m_address << endl;
cout << "学生学号:" << '\t' << std.m_number << endl;
return dist;
}

void Student::FileRead(ofstream &dist) const
{
dist.write(m_name.c_str(), sizeof(m_name));
dist.write((char *)&m_age, sizeof(int));
dist.write((char *)&m_mark, sizeof(int));
dist.write(m_address.c_str(), sizeof(m_address));
dist.write(m_number.c_str(), sizeof(m_number));
}//由于编译器不支持c99标准,因此调整书上的方法

istream &operator >> (istream &sour, Student &std)
{
cout << "请输入学生姓名" << endl;
cin >> std.m_name;
cout << "请输入学生年龄" << endl;
cin >> std.m_age;
cout << "请输入学生成绩" << endl;
cin >> std.m_mark;
cout << "请输入学生住址" << endl;
cin >> std.m_address;
cout << "请输入学生学号" << endl;
cin >> std.m_number;

return sour;
}

void Student::FileWrite(ifstream &sour)const
{
sour.read((char *)&m_name, sizeof(m_name));
sour.read((char *)&m_age, sizeof(int));
sour.read((char *)&m_mark, sizeof(m_mark));
sour.read((char *)&m_address, sizeof(m_address));
sour.read((char *)&m_number, sizeof(m_number));
}

template<typename T>class Array
{
private:
T *m_element;
int m_maxsize;
int m_last;
ifstream m_fin;
ofstream m_fout;
public:
Array(int max = 3);
~Array();
void Ordinsert(T &std);
bool IsFull(void);
void Renews(void);
void ShowInfo(void);
};

template<typename T>Array<T>::Array(int max)
{
m_element = new T[3];
assert(m_element != NULL);
m_maxsize = max;
m_last = -1;
m_fout.open("save info.data",ios::binary);
if (!m_fout)
{
cout << "文件创建失败,退出程序" << endl;
m_fout.close();
m_fout.clear();
system("pause");
exit(0);
}
else
{
while (!m_fout.eof())//这里无法读取到文件尾
{
T temp;
temp.FileRead(m_fout);
if(m_fout.eof()==0)
Ordinsert(temp);
}
m_fout.close();
m_fout.clear();
}
}


template<typename T>Array<T>::~Array()
{
int i;
m_fin.open("save info.data",ios::binary);
if (!m_fin)
{
cout << "找不到文件,退出程序" << endl;
m_fin.close();
m_fin.clear();
system("pause");
exit(0);
}
else
{
for (i = 0; i <= m_last; i++)
{
m_element[i].FileWrite(m_fin);
cout << "存储成功" << endl;
}
delete[]m_element;
m_fin.close();
}
}

template<typename T>bool Array<T>::IsFull(void)
{
return m_last == m_maxsize - 1;
}

template<typename T>void Array<T>::Renews(void)
{
int i;
T *temp = m_element;
m_element = new Student[2 * m_maxsize];
assert(temp != NULL);
m_maxsize = m_maxsize * 2;
for (i = 0; i <= m_last; i++)
{
m_element[i] = temp[i];
}
delete[]temp;
}

template<typename T>void Array<T>::Ordinsert(T &std)
{
int i, j;
if (IsFull())
{
Renews();
}
for (i = 0; i <= m_last; i++)
{
if (m_element[i] > std)
break;
}
if (i == m_last)
{
m_element[++m_last] = std;
}
else
{
for (j = i + 1; j <= m_last; j++)
{
m_element[j] = m_element[j - 1];
}
m_element[i] = std;
m_last++;
}
}

template<typename T>void Array<T>::ShowInfo(void)
{
int i;
cout << "现已登记的学生信息" << endl;
for (i = 0; i <= m_last; i++)
{
cout << m_element[i];
cout << endl;
}
}

int main(void)
{
Array<Student> mylist;
Student student;
char option;
cout << "是否登记新学生信息?Y or N" << endl;
option = _getch();
while (1)
{
if (option == 'Y')
{
cin >> student;
mylist.Ordinsert(student);
cin.ignore(1024, '\n');
cout << "是否继续输入?Y or N" << endl;
option = _getch();
}
else
{
mylist.ShowInfo();
cout << "退出程序" << endl;

break;
}
}
mylist.~Array();
system("pause");
return 0;
}

...全文
122 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
幻夢之葉 2017-05-14
  • 打赏
  • 举报
回复
string m_name; int m_age; double m_mark; string m_address; string m_number; 两个修改办法你参考下: 1: string全部改为char[] dist.write(m_address.c_str(), sizeof(m_name)); // sizeof(m_name)计算的大小是类的大小,string的字符串是动态分配给char的 sour.read((char *)&m_name, sizeof(m_name)); //反过来读取赋值没有意义,动态的指针是个运行时的东西,下次运行你把这个指针值赋予它,本身就是错误的 2: 格式化存储,不要使用二进制。读取到的字符串,然后赋值给string的变量

64,648

社区成员

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

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