2011-11-03 103 views
0

讀取字節我使用fstream的對象創建的字節讀/寫成一個二進制文件使用fstream的C++

#include <iostream> 
#include <fstream> 

using namespace std; 

#define COL_WIDTH 20 

int writeBinaryFile(char *desPath); 
int readBinaryFile(char *desPath); 

int age; 
char name[COL_WIDTH]; 
int recsize = sizeof(int)+sizeof(name); 
int n; 

int main(){ 

    char desPath[MAX_PATH+1]; 
    char input[2]; 

    while(true){ 
     cout << "Main Menu:\n1 Write Binary File\n2 Read Binary File\n3 EXIT" << endl; 
     cin.getline(input, 2);   


     if(atoi(input)== 1){ 
      cout << "Enter destination path:" << endl; 
      cin.getline(desPath, MAX_PATH+1); 
      for(;;){ 
       int output = writeBinaryFile(desPath); 
       if(output == 1) break; 
       else if(output == 2) { *input = '4'; break;} 
      } 
     } 
     else if(atoi(input) == 2){ 
      cout << "Enter destination path:" << endl; 
      cin.getline(desPath, MAX_PATH+1); 
      for(;;){ 
       int output = readBinaryFile(desPath); 
       if(output == 1) break; 
       else if(output == 2){ *input = '4'; break;} 
      } 
     } 

     else if(atoi(input) == 3) 
      break; 
     else cout << "You entered wrong input, enter only 1 or 2." << endl; 

     if(atoi(input) == 4) continue; 
     else break; 

    } 

    system("pause"); 
    return 0; 
} 

int writeBinaryFile(char *desPath){ 
    char option[2]; 
    fstream wBin(desPath, ios::binary | ios::out); 
    if(!wBin){ 
     cout << desPath << " is not good path."<< endl; 
     return 1; 
    } 
    cout << "Enter name: " << endl; 
    cin.getline(name,COL_WIDTH); 
    cout << "Enter age: " << endl; 
    cin >> age; 

    cout << "Enter record number: " << endl; 
    cin >> n; 

    wBin.seekp(n*recsize); 
    wBin.write(name, sizeof(name)); 
    wBin.write((char*)&age, sizeof(age)); 
    wBin.close(); 

    cout << "Enter record again? Press:" << endl 
     << "Enter to continue" << endl 
     << "Q to quit" << endl 
     << "M to go back to main menu" << endl; 

    cin.ignore(256,'\n'); 
    cin.getline(option,2); 

    if(option[0] == 'q' ||option[0] == 'Q') return 1; 
    else if(option[0] == 'm' ||option[0] == 'M') return 2; 

    return 0; 
} 


int readBinaryFile(char *desPath){  
    char option[2]; 
    fstream rBin(desPath, ios:: binary | ios:: in); 
    if(! rBin){ 
     cout << "File not found!" << endl; 
     return 1; 
    } 
    cout << "What record number?" <<endl; 
    cin >> n; 
    rBin.seekp((n*recsize)); 
    rBin.read(name,sizeof(name)); 
    rBin.read((char*)&age, sizeof(int)); 


    cout << name <<endl; 
    cout << age << endl; 
    rBin.close(); 
    cout << "Print more? Press enter. Press Q to QUIT or M to go back." << endl; 
    cin.clear(); 
    cin.sync(); 
    cin.getline(option, 2); 

    if(option[0] == 'q'|| option[0] == 'Q'){rBin.close(); return 1;} 
    else if(option[0] == 'm' || option[0] == 'M'){rBin.close(); return 2;} 

    return 0; 
} 

我創建二進制文件首先用的姓名,年齡,recordnumber(字節位置,這是0)然後在第二個循環我輸入名稱,年齡,記錄編號2. 當我試圖讀取字節pos(0)的第一對(char *,int),但它返回錯誤的結果,但是當我試圖讀取最後一對pos (1)它返回正確的結果。

我也嘗試了3次輸入,但只有最後一個char *和int是正確的。

爲什麼在第一個字節(名稱(20字節),年齡(4字節))中出現錯誤的結果,但是最後得到的字節正確?

+2

你的問題是什麼?你錯誤和正確的結果是什麼? –

+0

我不會立即發現任何問題。我必須運行它才能找到問題。你跑過去了嗎? –

+0

當我創建bin文件我輸入ff:name:name1,age:1,recordnum:0然後在第二個循環name2,2,1然後在第三個循環name3,3,2 ...我希望得到當我輸入0 for recordnum ..name1,1但我只是空白,0 ...與recordnum 1相同..但與recordnum 2,我沒有得到正確的名稱3,3 ... – jko

回答

2

在每次調用writeBinaryFile時,都會重新打開輸出,破壞文件的先前內容。您需要使用ios::binary | ios::ate | ios::out | ios::in

但是,這個位掩碼將而不是如果它不存在文件創建。您可以使用此代碼序列解決該問題:

int writeBinaryFile(char *desPath) { 
    ... 
    // Create the file only if it doesn't exist 
    fstream(desPath, ios::binary|ios::out|ios::app); 

    // Now it exists -- open it 
    fstream wBin(desPath, ios::binary|ios::out|ios::in); 
    ... 
} 

Credit @JoeFish用於答案的有用部分。

+0

謝謝!這很有幫助! – jko