ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 실습 7
    정리필요2 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가 되는가?

Designed by Tistory.