p113.cpp

来自「《C++编程指南(续编)》的一些程序源代码」· C++ 代码 · 共 245 行

CPP
245
字号
#include <fstream.h>
#include <strstrea.h>
#include <iomanip.h>
#include <string.h>
#include <ctype.h>

char * makeCopy(char * pszS)
{
	char * pszT=new char[strlen(pszS)+1];
	strcpy(pszT,pszS);
	return pszT;
}

class Student
{
public:
	Student(char * pLN,char * pFN,
		int nGrd,unsigned long ulId);

	virtual ~Student();
	virtual void display(ostream& out)const;
	virtual void save(ostream& out);
	static Student * restore(istream& in);

protected:
	char * pLName;
	char * pFName;
	int nGrade;
	unsigned long ulID;

	static void restoreStudent(istream& in,
		char * pszLName,char * pszFName,
		int& nGrade,unsigned long& ulID);
};

Student::Student(char * pLN,char * pFN,
				 int nGrd,unsigned long ulId)
{
	pLName=makeCopy(pLN);
	pFName=makeCopy(pFN);

	nGrade=nGrd;
	ulID=ulId;
}

Student::~Student()
{
	delete pLName;
	delete pFName;
}

void Student::display(ostream& out)const
{
	out<<pLName<<" , "<<pFName
		<<" - "<<ulID
		<<"(Grade"<<nGrade<<")";
}
void Student::save(ostream& out)
{
	out<<"S"
		<<"<"<<pLName<<">"
		<<"<"<<pFName<<">"
		<<nGrade<<" "
		<<ulID<<"\n";
}
void Student::restoreStudent(istream& in,
							 char * pszLName,char * pszFName,
							 int& nGrade,unsigned long& ulID)
{
	if(in.get()!='<')
	{
		in.clear(ios::failbit);
	}
	in.getline(pszLName,80,'>');
	if(in.get()!='<')
	{
		in.clear(ios::failbit);
	}
	in.getline(pszFName,80,'>');

	in>>nGrade>>ulID;

	return;
}
Student * Student::restore(istream& in)
{
	char buffer[80];

	if(in.get()!='S')
	{
		in.getline(buffer,sizeof buffer);
		in.clear(ios::failbit);
		return (Student *)0;
	}
	char szLastName[80];
	char szFirstName[80];
	int nGrade;
	unsigned long ulID;
	restoreStudent(in,szLastName,szFirstName,nGrade,ulID);
	if(in.fail())
	{
		return (Student * )0;
	}

	if(strlen(szLastName)==0||
		strlen(szFirstName)==0||
		nGrade<-2||nGrade>12)
	{
		in.clear(ios::failbit);
		return (Student * )0;
	}

	in.getline(buffer,sizeof buffer);

	return new Student(szLastName,szFirstName,nGrade,ulID);
}
ostream& operator<<(ostream& out,const Student& s)
{
	s.display(out);
	return out;
}

class BandStudent:public Student
{
public:
	BandStudent(char * pLN,char * pFN,
		int nGrd,unsigned long ulId,
		char * pInstrument);

	~BandStudent();
	virtual void save(ostream&);
	static Student * restore(istream&);

	virtual void display(ostream& out)const;

protected:
	char * pszInstrument;
};
BandStudent::BandStudent(char * pLN,char * pFN,
						 int nGrd,unsigned long ulId,
						 char * pInstrument):
Student(pLN,pFN,nGrd,ulId)
{
	pszInstrument=makeCopy(pInstrument);
}
BandStudent::~BandStudent()
{
	delete pszInstrument;
}
void BandStudent::display(ostream& out)const
{
	Student::display(out);
	out<<"["<<pszInstrument<<"]";
}
void BandStudent::save(ostream& out)
{
	out<<"B"
		<<"<"<<pLName<<">"
		<<"<"<<pFName<<">"
		<<nGrade<<" "
		<<ulID<<" "
		<<"<"<<pszInstrument<<">"
		<<"\n";
}
Student * BandStudent::restore(istream& in)
{
	char buffer[80];
	if(in.get()!='B')
	{
		in.getline(buffer,sizeof buffer);
		in.clear(ios::failbit);
		return (Student * )0;
	}
	char szLastName[80];
	char szFirstName[80];
	int nGrade;
	unsigned long ulID;
	restoreStudent(in,szLastName,szFirstName,nGrade,ulID);
	if(in.fail())
	{
		return (Student * )0;
	}
	if(strlen(szLastName)==0||
		strlen(szFirstName)==0||
		nGrade<-2||nGrade>12)
	{
		in.clear(ios::failbit);
		return (Student * )0;
	}
	if(in.get()!=' '||in.get()!='<')
	{
		in.getline(buffer,sizeof buffer);
		in.clear(ios::failbit);
		return (Student * )0;
	}
	char szInstrument[80];
	in.getline(szInstrument,sizeof szInstrument,'>');
	if(strlen(szInstrument)==0)
	{
		in.clear(ios::failbit);
		return (Student * )0;
	}
	in.getline(buffer,sizeof buffer);

	return new BandStudent(szLastName,szFirstName,
		nGrade,ulID,szInstrument);
}

int main(int ,char **)
{
	ifstream fin("D:\\sfile.txt");
	if(fin.fail())
	{
		cout<<"Error opening file sfile.txt\n";
		return -1;
	}
	int i=0;
	Student * psStudent;
	for(;;)
	{
		char szBuffer[80];
		fin.getline(szBuffer,sizeof szBuffer);		

		istrstream sin(szBuffer,sizeof szBuffer);
		psStudent=Student::restore(sin);
		if(sin.fail())
		{
			istrstream bsin(szBuffer,sizeof szBuffer);
			psStudent=BandStudent::restore(bsin);

			if(bsin.fail())
			{
				cout<<"Error reading"<<++i<<"th line\n";
				continue;
			}
		}
		cout<<" # "<<++i<<" - "<<(*psStudent)<<"\n";
		delete psStudent;

		if(fin.eof())
		{
			return 0;
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?