2012-12-06 4 views
0

이 파일에는 항상 Fraction 구조가 추가로 포함되어 있습니까? 사용자가 옵션 3을 입력하여 프로그램이 시작될 때 모든 분수를 보려면 (파일이 비어 있어야 함) 0/0이 인쇄됩니다. 사용자가 옵션 1을 선택하고 분수 1/1을 입력 한 다음 옵션 3을 선택하면 두 개의 분수가 1/1 1/1으로 인쇄됩니다..dat 파일 읽기 및 쓰기

참고 :이 작업을 실행하는 당신은라는 빈 .dat 파일을 작성해야합니다 "fractions.dat"

난 정말 당신의 도움을 주셔서 감사합니다!

#include <iostream> 
#include <fstream> 

using namespace std; 

struct Fraction 
{ 
    int num, den; 
}; 

int search(fstream& file, Fraction* f); 
int menu(); 
void proccessChoice(int i); 
Fraction* readFrac(); 

Fraction* fracs[100]; 
int index; 
string fileName = "fractions.dat"; 
fstream file(fileName, ios::in | ios::out | ios::binary | ios::trunc); 

//structure called Fraction with num and den as its only integer members 
int main() 
{ 
    if (!file) 
    { 
     cout << "Error opening file. Program aborting.\n"; 
     system("pause"); 
     exit(1); 
    } 
    int choice; 
    do 
    { 
     choice = menu(); 
     proccessChoice(choice); 
    } while(choice != 4); 


    system("pause"); 
    return 0; 
} 



int menu() 
{ 
    int c; 
    cout << "1.Enter new fraction" << endl; 
    cout << "2.Display/update a fraction" << endl; 
    cout << "3.Display all fractions" << endl; 
    cout << "4.Quit" << endl; 
    cin >> c; 
    return c; 
} 

void proccessChoice(int i) 
{ 
    switch(i) 
    { 
    case 1: 
     { 
      cout << "Enter a fraction to add: "; 
      fracs[index] = readFrac(); 
      file.seekp(0, ios::end); 
      file.write(reinterpret_cast<char*>(fracs[index]), sizeof(Fraction)); 
      /*cout << fracs[index]->num << "/" << fracs[index]->den ;*/ 
      index++; 
     } 
      break; 
    case 2: 
     { 
      cout << "Enter fraction to view/update: "; 
      Fraction* fToFind = readFrac(); 
      int i = search(file, fToFind); 
      if (i == -1) 
      { 
       cout << "Fraction not found." << endl; 
      } 
      else 
      { 
       char r; 
       cout << fToFind->num << "/" << fToFind->den << " found at index " << i << ". Update? [y/n]"; 
       cin >> r; 
       if(r == 'y' || r == 'Y') 
       { 
        cout << "Enter a new fraction: "; 
        Fraction* fToWrite = readFrac(); 
        file.seekp(sizeof(Fraction) * (i)); 
        file.write(reinterpret_cast<char*>(fToWrite), sizeof(Fraction)); 
       } 
      } 
      cout << i << endl; 
      cout << "Case 2" << endl; 
     } 
      break; 
    case 3: 
     { 
      Fraction* cur = new Fraction(); 
      //int pos = -1; 
      if (!file) 
      { 
       cout << "Error opening file. Program aborting.\n"; 
       system("pause"); 
       exit(1); 
      } 
      file.seekg(0, ios::beg); 
      while(!file.eof()) 
      { 
       file.read(reinterpret_cast<char *>(cur), sizeof(Fraction)); 
       cout << cur->num << "/" << cur->den << endl; 
      } 
        cout << "Case 3" << endl; 
     } 
      break; 
    } 
} 

int search(fstream& file, Fraction* f) 
{ 
    Fraction* cur = new Fraction(); 
    int pos = -1; 
    if (!file) 
    { 
     cout << "Error opening file. Program aborting.\n"; 
     system("pause"); 
     exit(1); 
    } 
    file.seekg(0, ios::beg); 
    while(!file.eof()) 
    { 
     file.read(reinterpret_cast<char *>(cur), sizeof(Fraction)); 
     if((cur->num == f->num) && (cur->den == f->den)) 
     { 
      cout << "\nFrac found!" << cur->num << "/" << cur->den<<endl; 
      pos = file.tellg()/sizeof(Fraction) - 1; 
      return pos; 
     } 
    } 
    return pos; 
} 

Fraction* readFrac() 
{ 
    Fraction* f = new Fraction(); 
    char slash; 
    cin >> f->num >> slash >> f->den; 
    return f; 
} 

시도 솔루션 1 : 모든 분수를 볼 수있는 사용자의 첫 번째 시도 작동하지만 두 번째 시도에서 파일을 찾을 수 없습니다.

case 3: 
     { 
      Fraction* cur = new Fraction(); 
      //int pos = -1; 
      if (!file) 
      { 
       cout << "Error opening file. Program aborting.\n"; 
       system("pause"); 
       exit(1); 
      } 
      file.seekg(0, ios::beg); 
      while(!file.eof()) 
      { 
       if(file.read(reinterpret_cast<char *>(cur), sizeof(Fraction)).gcount()== sizeof(Fraction)) 
       { 
        cout << cur->num << "/" << cur->den << endl; 
       } 
      } 
        cout << "Case 3" << endl; 
     } 
      break; 
    } 

답변

1

아직 파일의 끝에 도달하지 않았기 때문에!

while(!file.eof()) 

당신은 그러나, 읽기 커서 위치 0에 현재주의, 빈 파일을 열었습니다. 데이터를 읽으려고 시도하지 않은 한, 커서의 끝까지 파일의 끝에 도달하지 않았으므로 file.eof()은 false가됩니다.

당신은 당신이 실제로 분수 추출 할 수 있었다 여부를 확인해야합니다 : I 시도

std::istream& operator>>(std:istream& in, Fraction& f){ 
    return in.read(reinterpret_cast<char *>(&f), sizeof(Fraction)); 
} 

// .... 
while(file >> *cur){ 
    // ... your code. 
} 
+0

:이에 대한 사용자 정의 연산자를 제공하는 경우이 훨씬 간단 얻는 것을

if( file.read(reinterpret_cast<char *>(cur), sizeof(Fraction)).gcount() == sizeof(Fraction) ){ // Fraction has been extracted } else // either eof() or some other error. 

주 당신의 첫 번째 제안. 옵션 3을 처음 실행할 때 유용하지만 옵션 3을 다시 선택하면 파일을 찾을 수 없습니다 (질문에 대한 업데이트 참조). – Zzz

+0

오류 오류 C2678 : 이진수 >> >> : 'std :: fstream'형식의 왼쪽 피연산자를 사용하는 연산자가 없습니다 (또는 수락 가능한 변환이 없음) – Zzz

+0

@ Azzi : 음, 파일이 발견되었습니다. 그러나, 그것은 나쁜 상태에 있으며, 이것은'! file'을 참으로 평가할 것입니다. 파일이 열렸는지를 알고 싶다면 대신'.is_open()'을 사용해야한다. 오래된 에러 상태를 지우려면'.clear()'를 사용할 필요가 있다는 것을 명심하십시오. – Zeta