정리필요2

실습 7

ShineWithMe 2008. 9. 1. 23:33

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

const int MAXNAME = 20;
const int MAXSIZE = 10;

class StudentRecord
{
private:
 int sno;
 string sname; // 또는 char sname[MAXNAME] 사용
 float score;
public:
 StudentRecord() {;}
 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 writeToFile(ofstream&);
 void printRecord(ostream&);
 int size();
};
void StudentRecord::writeToFile(ofstream& BinOut)// 이진파일에 쓰기
{
 BinOut.write((char*) &sno, sizeof(int));    // 4
 int namelen = (int)sname.length();      
 BinOut.write((char*) &namelen, sizeof(int));   // 4
 BinOut.write(sname.c_str(), (std::streamsize)namelen); // sname.length()
 BinOut.write((char*) &score, sizeof(float));   // 4
}

void StudentRecord::readFromFile(ifstream& Bin)// 이진파일 읽기
{
 // 가변길이로
 int len;
 Bin.read((char*) &sno, sizeof(int));  // 4
 Bin.read((char*) &len, sizeof(int));  // 4
 char* name = new char[len+1];
 Bin.read(name, (std::streamsize)len);  // sname.length()
 name[len] = '\0';
 sname = name;
 Bin.read((char*) &score, sizeof(float)); // 4
}

void StudentRecord::printRecord(ostream&)// 화면에 출력
{
 // 채워야 할 부분
 cout << sno <<'\t'<< sname <<'\t'<< score <<endl;
}

int StudentRecord::size()
{
 return sizeof(sno) + sizeof(int) + (int)sname.length() + sizeof(score);
}

class KeyIndex
{
private:
 int key;
 int Offset;
 //int RRN;
public:
 KeyIndex() {;}
 KeyIndex(int k, int r) {key = k, Offset = r;}
 void Set(int k, int r) {key = k, Offset = r;}
 int getKey() const {return key;}
 int getOffset() const {return Offset;}
};


template <class Type>
class Sort
{
private:
 void exchange(Type &a, Type &b);
public:
 void bubble(KeyIndex *data, int n);
};

template <class Type> //버블소트로 인덱스정렬
void Sort<Type>::bubble(KeyIndex *data, int n)
{

 int i=0, j=0;
  for(i=0; i<n; i++)
   for(j=0; j<n; j++)
    if(data[i].getKey() < data[j].getKey())
     exchange(data[i], data[j]);
}

template <class Type> // 교환함수
void Sort<Type>::exchange(Type &a, Type &b)
{
 Type c;
 c=a;
 a=b;
 b=c;
}


int main(int argc, char* argv[])
{
 StudentRecord S[MAXSIZE], R[MAXSIZE];
 string sname; // 레코드저장할임시변수
 int sno;
 float score;

 // 루프 변수

 ifstream textin(argv[1]);

 int i=0, n=0;
 // student 파일에서 레코드 읽어 배열에 저장
 while (textin.good() && textin.peek() != EOF)
 {
  textin >> sno >> sname >> score;
  textin.ignore(300, '\n');
  S[i].setSno(sno);
  S[i].setSname(sname);
  S[i].setScore(score);
  i++;
 }

 if(!textin.is_open())
 {
  cout << "파일을 열수 없습니다. " << endl;
  return 0;
 }

 ofstream binout("binout.bin", ios::binary);
 for(int j=0; j<i; j++)
  S[j].writeToFile(binout);
 binout.close();
 // 이진파일 생성했다.

 ifstream binin("binout.bin", ios::binary);

 KeyIndex *K = new KeyIndex[i]; // 인덱스정렬 할 배열
 cout << "이진파일로 바꾼내용을 출력" << endl;
 for(int k=0; k<i; k++)
 {
  K[k].Set(S[k].getSno(), binin.tellg());
  R[k].readFromFile(binin);
  R[k].printRecord(cout);
 }
 binin.close(); // 이진파일 출력

 //Sort<KeyIndex> sort;
 //sort.bubble(K, i); // 인덱스배열 [K]를 학번에 따라 정렬


 ifstream bintest("binout.bin", ios::binary);
 StudentRecord *TEST = new StudentRecord;

 string input;
 int num;
 bool flag = false;


 cout << "학생레코드를 찾아보시겠습니까? (Y/N)" << endl;
 cin >> input;
 
 while(input == "y" || input =="Y")
 {
  cout << "학번을 입력해주세요" << endl;
  cin >> num;
 
  flag = false;
  for(int t=0; t<i; t++)
  {
   if(K[t].getKey() == num)
   {
    flag = true;
    bintest.seekg(K[t].getOffset(), ios::beg);
    TEST->readFromFile(bintest);
    cout << "---------------------------"<< endl;
    TEST->printRecord(cout);
   }
  }
  bintest.clear();
  bintest.seekg(0, ios::beg);

  if(flag==false)
  {
   cout << "찾는 학번이 없습니다. " << endl;
  }
  cout << "계속 입력을 받으시겠습니까? ( Y/N )" <<endl;
  cin >> input;
 }

 bintest.close();

 //delete TEST;
 delete K;
 return 0;
}


// Student 레코드에 받으면문자열은 왜 다 32byte가 되는가?