2011-11-03 68 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