-
#include <iostream>
#include <fstream>
#include <string>
using namespace std;class node // 링크리스트 노드 클래스
{ // friend class로 StudentRecord 설정
friend class StudentRecord;
public:
int sno;
string sname;
float score;
node *link;
};node *ptr; // 리스트 root
class StudentRecord
{
private:
int sno;
string sname;
float score;public:
StudentRecord()
{ // 노드의 초기화
ptr = new node;
ptr->sno = 0;
ptr->sname = "";
ptr->score = 0;
ptr->link = NULL;
}StudentRecord(int no, string name, float s) {sno=no, sname=name, score=s;}
void setSno(int no) {sno = no;}
void setSname(string name) {sname = name;}
void setScore(float s) {score = s;}int getSno() const {return sno;}
string getSname() const {return sname;}
float getScore() const {return score;}void readFromFile(ifstream&); // 파일에서 읽는 함수
void printRecord(ostream&); // 레코드 출력 함수
bool operator== (StudentRecord s); // operator == 재정의 함수
void addback(); // 리스트 맨뒤에 새노드추가 함수
};
bool is_NodeNull(node *p1) // 노드가 NULL인지 검사 함수
{
if(p1->sno==0 && p1->sname =="" && p1->score == 0)
return false;
else
return true;
}void exchange(node *x, node *y) // 노드값 교환 함수
{
node* temp = new node;
// 다음노드의 포인터를 제외한 나머지 교환
temp->sno = x->sno;
temp->sname = x->sname;
temp->score = x->score;
x->sno = y->sno;
x->sname = y->sname;
x->score = y->score;
y->sno = temp->sno;
y->sname = temp->sname;
y->score = temp->score;
}void bubble(node *p) // 리스트 정렬
{
node *q = new node;
q = p;
while (q)
{
node *p1 = new node;
*p1 = *q;
while(p1)
{
if(p1->sno < q->sno)
exchange(p1, q);
p1 = p1->link;
}
delete p1;
q = q->link;
}
p = q;
delete q;
}
bool StudentRecord::operator== (StudentRecord s) // == 연산자 재정의
{
if(this->sno==s.sno && this->sname==s.sname && this->score==s.score)
return true;
else
return false;
}void StudentRecord::readFromFile(ifstream& Bin)// 이진파일 읽기
{
int len;
char* name = new char[20];
Bin.read((char*) &sno, sizeof(int));
Bin.read((char*) &len, sizeof(int));
Bin.read((char*) name, (std::streamsize)len);
name[len] = '\0';
sname = name;
Bin.read((char*) &score, sizeof(float));
}void StudentRecord::addback()
{ // 새 레코드를 리스트 맨뒤에 추가
node *pt = new node;
node *temp = new node;
pt = ptr;temp->sno = this->sno;
temp->sname = this->sname;
temp->score = this->score;
// 리스트의root인 ptr에 값이 있는지
// 검사해 있으면 없을때 까지 리스트
// 하위로 내려가 끝에 새노드 추가
if(is_NodeNull(ptr))
{
while(pt->link)
{
pt = pt->link;
}temp->link = NULL;
pt->link = temp;
}
else
{
temp->link = NULL;
ptr = temp;
}
}
void printList(node *ptr)// 리스트를 화면에 출력
{
node *p1;
p1 = ptr;
while(p1)
{
cout << p1->sno <<'\t'<< p1->sname <<'\t'<< p1->score <<endl;
p1 = p1->link;
}}
float average(node *ptr)// 리스트의 score들의 평균
{
node *p1;
p1 = ptr;
int cnt=0;
float average=0;
while(p1)
{
average += p1->score;
p1 = p1->link;
cnt++;
}
return average/cnt;}
void StudentRecord::printRecord(ostream&)// 레코드를 화면에 출력
{
// 채워야 할 부분
cout << sno <<'\t'<< sname <<'\t'<< score <<endl;
}
void writeToFile(ofstream& BinOut, node *ptr)// 리스트를 이진파일에 쓰기
{
node *p1; // 임시노드
p1 = ptr;
while(p1)
{
// 채워야 할 부분
int namelen = (int)p1->sname.length();
BinOut.write((char*) &p1->sno, sizeof(int));
BinOut.write((char*) &namelen, sizeof(int));
BinOut.write(p1->sname.c_str(), (std::streamsize)namelen);
BinOut.write((char*) &p1->score, sizeof(float));
p1 = p1->link; // 다음 노드
}
}
int main(int argc, char* argv[])
{
StudentRecord S, R; // 임시 저장 레코드 S, Rifstream BinStudent(argv[1], ios::binary); // 파일열기
ofstream Binout("output.bin", ios::binary);if(!BinStudent.is_open()) // 파일열기 검사
{
cout << "파일을 열수 없습니다. " << endl;
return 0;
}while (BinStudent.peek() != EOF) // 파일을 임시 레코드로 읽어
{ // 임시레코드를 리스트에 추가
S.readFromFile(BinStudent);
S.addback();
}bubble(ptr); // 리스트 정렬
cout << "-----Sorted List(origin:student.bin)-----" << endl;
cout << "[Num.]\t[Name]\t\t[Score]"<< endl;
printList(ptr); // 리스트 화면 출력
cout << "# Average Score : " << average(ptr) << endl; // 평균 화면 출력
writeToFile(Binout, ptr); // 리스트 파일 출력Binout.close(); // output.bin 파일 ifstream으로 다시열기
ifstream BinStudentSorted("output.bin", ios::binary);BinStudent.clear(); // 파일객체 리프래쉬
BinStudent.seekg(0, ios::beg);
BinStudentSorted.clear();
BinStudentSorted.seekg(0, ios::beg);bool bc = true; // flag
int findex = 0, sindex = 0; // 레코드 수를 저장할 변수
while (BinStudent.peek() != EOF)
{
S.readFromFile(BinStudent);
findex++; //첫번째 파일의 레코드수
}
while (BinStudentSorted.peek() != EOF)
{
R.readFromFile(BinStudentSorted);
sindex++; //두번째 파일의 레코드수
}//레코드 수검사
cout << "\n파일 일치하는가?" << endl;
if(findex != sindex)
{
cout << " 파일이 다릅니다.\n" << endl;BinStudent.clear(); // 파일객체 리프래쉬
BinStudentSorted.clear();
BinStudent.seekg(0, ios::beg);
BinStudentSorted.seekg(0, ios::beg);cout << "student.bin " << endl; // 화면출력
cout << "[Num.]\t[Name]\t\t[Score]"<< endl;
while (BinStudent.peek() != EOF)
{
S.readFromFile(BinStudent);
S.printRecord(cout);
}cout << endl << "output.bin" << endl;
cout << "[Num.]\t[Name]\t\t[Score]"<< endl;
while (BinStudentSorted.peek() != EOF)
{
R.readFromFile(BinStudentSorted);
R.printRecord(cout);
}
return 0;
}
// 레코드 내용이 같으지 검사
while (BinStudent.peek() != EOF)
{
S.readFromFile(BinStudent);
while(BinStudentSorted.peek() != EOF)
{
R.readFromFile(BinStudentSorted);
if(S==R) // 두 레코드가 같은지 검사
bc = true; // flag 에 true
else
bc = false; // flag 에 false
}
}//결과 출력
if(bc==true) // flag가 true이면 같고 flase면 다르므로
{ // 두파일의 일치여부와 내용을 화면출력
cout << " \n\n 파일이 같습니다. \n\n" << endl;BinStudent.clear();
BinStudentSorted.clear();
BinStudent.seekg(0, ios::beg);
BinStudentSorted.seekg(0, ios::beg);cout << "-----student.bin----- " << endl;
cout << "[Num.]\t[Name]\t\t[Score]"<< endl;
while (BinStudent.peek() != EOF)
{
S.readFromFile(BinStudent);
S.printRecord(cout);
}cout << endl << "-----output.bin-----" << endl;
cout << "[Num.]\t[Name]\t\t[Score]"<< endl;
while (BinStudentSorted.peek() != EOF)
{
R.readFromFile(BinStudentSorted);
R.printRecord(cout);
}
}
else
{
cout << " \n\n파일이 다릅니다.\n\n" << endl;BinStudent.clear();
BinStudentSorted.clear();
BinStudent.seekg(0, ios::beg);
BinStudentSorted.seekg(0, ios::beg);cout << "-----student.bin-----" << endl;
while (BinStudent.peek() != EOF)
{
S.readFromFile(BinStudent);
S.printRecord(cout);
}cout << endl << "-----output.bin-----" << endl;
while (BinStudentSorted.peek() != EOF)
{
R.readFromFile(BinStudentSorted);
R.printRecord(cout);
}
return 0;
}BinStudent.close(); // 파일 닫기
BinStudentSorted.close();return 0;
}