2010-05-01 98 views
1

我需要製作一個包含「name」的文件,該文件是一個char-和「data」的字符串數組,它是字節數組 - 在C++中的字符數組 - 但第一個我面臨的問題是如何將「名稱」與「數據」分開?換行符可以在這種情況下工作(假設名稱中沒有「\ n」),但在「數據」部分中可能有特殊字符,因此無法知道它何時結束,因此我將在具有「數據」大小的數據之前的文件中的int值! 我試着用代碼來做到這一點如下:在C++中讀取和寫入二進制文件

if((fp = fopen("file.bin","wb")) == NULL) 
{ 
    return false; 
} 
char buffer[] = "first data\n"; 
fwrite(buffer ,1,sizeof(buffer),fp); 
int number[1]; 
number[0]=10; 
fwrite(number ,1,1, fp); 
char data[] = "1234567890"; 
fwrite(data , 1, number[0], fp); 
fclose(fp); 

,但我不知道是否「INT」部分是正確的,所以我嘗試了許多其他的代碼包括這一個:

char buffer[] = "first data\n"; 
fwrite(buffer ,1,sizeof(buffer),fp); 
int size=10; 
fwrite(&size ,sizeof size,1, fp); 
char data[] = "1234567890"; 
fwrite(data , 1, number[0], fp); 

當我打開它而不是看到一個整數時,我在文件中看到4個「NULL」字符。這是正常的嗎? 我面臨的另一個問題是再次從文件中讀取!我嘗試閱讀的代碼根本沒有工作:(我嘗試使用「fread」,但我不確定是否應該使用「fseek」,或者只是讀取其後的其他字符。

我想用一個類爲以下內容,然後寫入和讀取回來的:

class Sign 
{ 
public: 
char* name; 
int size; 
char* data; 
}; 

但是這不是在C一件容易的事情++!

我也試過如下:

void saveData(char* filename) { 

    fstream filestr; 
    int n; 
    n=10; 
    char* data= "1234567890"; 

    filestr.open (filename, fstream::out | fstream::binary); 
    for (int j = 0; j<5 ; j++) 
    { 
     filestr << n; 

     for (int i = 0; i < n; i++) { 
      filestr << data[i]; 
     } 
    } 
    filestr.close(); 
} 

void readData(char* filename) { 
    fstream filestr; 
    int n =0; 

    filestr.open (filename, fstream::in | fstream::binary); 
    int m =0; 
    //while(!filestr.eof()) 
    while(m<5) 
    { 
     filestr >> n; 

     char *data = new char[n]; 
     for (int i = 0; i < n; i++) { 
      filestr >> data[i]; 
     } 
     printf("data is %s\n",data); 
     m++; 
    } 
    filestr.close(); 
} 

但是閱讀也沒有工作。

在閱讀我越來越奇怪的字符。


到目前爲止,對我的作品的代碼是這樣的:

void saveData(char* filename) { 
    fstream filestr; 
    char * name = "first data\n"; 
    int n; 
    n=10; 
    char* data= "asdfghjkl;"; 

    filestr.open (filename, fstream::out | fstream::binary); 
    for (int j = 0; j<5 ; j++) 
    { 
     filestr << name; 
     filestr << strlen(data); 
     filestr << data; 
    } 
    filestr.close(); 
} 


void readData(char* filename) { 
    fstream filestr; 
    int n =0; 

    filestr.open (filename, fstream::in | fstream::binary); 
    while(!filestr.eof()) 
    { 
     string name; 
     getline(filestr,name,'\n'); 
     printf("name is %s\n",name.c_str()); 

     filestr >> n; 

     char *data = new char[n]; 
     for (int i = 0; i < n; i++) { 
      filestr >> data[i]; 
     } 
     printf("n is%d\ndata is %s\n",n,data); 
    } 
    filestr.close(); 
} 

但在閱讀的問題是:

1-(我不認爲這是一個真正的問題),它打印除實際數據以外的其他字符。 2-對readData函數我得到輸出次(在我最後一次獲得每場作爲一個空場),而我只寫了次!任何人都知道這是爲什麼?與while(!filestr.eof())有關?

感謝您的幫助

+0

我嘗試使用READDATA功能,我只寫了讀取數據,但我從printf的輸出爲「代碼是ASDFGHJKL;²²²²▌▌1US \♀+「當數據是char * data =」asdfghjkl;「時,任何人都知道這是爲什麼? – Reem 2010-05-01 17:58:46

回答

0

好了,你的代碼的幾個問題:

fwrite(buffer ,1,sizeof(buffer),fp); 

的功能被定義爲這樣的:

size_t fwrite (const void * ptr, size_t size, size_t count, FILE * stream); 

所以你在發送緩衝區內的信息,稱它的大小爲1,並計算sizeof(buffer)。這可能適用於某些事情,但通常是倒退。嘗試使用:

fwrite(buffer, sizeof(char), strlen(buffer), fp); 

這兩個字符寬度獨立,沒有常數值,你需要擔心(它將適用於基本上任何字符串)。

在此另一個次要的事情:

int number[1]; 

你有一個整數,所以你只需要使用:

int number; 

如果你改變它後fwrite遇到錯誤,請使用以下調用:

fwrite(&number, sizeof(int), 1, fp); 

這會將一個整數值寫入文件。

解決這個問題後,看看你的代碼是否工作。糾正這些電話的問題肯定會更容易。 :)

此外,如果您打算使用字段長度(作爲整數寫入文件),您將需要設置某種類型的系統來讀取長度,然後是數據,並且您應該可能有每個字段的長度。使用類是絕對最簡單的方法來處理。

編輯: 您可能希望使用結構和函數而不是類,或者您可以使用帶有方法的類。這並不重要,兩者都很簡單。結構/ FUNC:

struct Record 
{ 
    std::string name, data; 
}; 

void writeRecord(Record thisRecord, std::string filename, size_t offset) 
{ 
    if ((fp = fopen(filename.c_str(), "wb")) == NULL) { return NULL; } 

    fwrite(thisRecord.size(), sizeof(unsigned int), 1, fp); // assuming size() return uint 
    fwrite(thisRecord.name.c_str(), sizeof(char), name.size(), fp); 

    // repeat for data or other fields 
    fclose(fp); 
} 
+0

strlen(buffer)和sizeof(buffer)之間有什麼區別? 至於整數,我仍然看到「NULL」「NULL」「NULL」! 請你能告訴我如何在這種情況下使用一個類?我試過了,但沒有奏效,我認爲它比我做的要複雜一些:( – Reem 2010-05-01 16:34:06

+2

Strlen(緩衝區)將計算緩衝區中的字符數(例如,「aaa」將返回3)Sizeof(緩衝區)將返回緩衝區中的字節數如果使用的是Unicode,則一個字符可以是兩個字節,因此差異會變得顯着 至於整數,除非您有一個很大的數字,否則期望一個或兩個在你的文件中,數字32會寫爲0x00 0x00 0x00 0x20。 – ssube 2010-05-01 17:16:27

3

首先,你的讀/寫的二進制格式應該像這樣(這裏read_num這種閱讀順序後,將包含10)。

FILE* fp = fopen("file.bin", "wb"); 
    int num = 10; 
    fwrite(&num, sizeof(int), 1, fp); 
    fclose(fp); 

    FILE* fp2 = fopen("file.bin", "rb"); 
    int read_num; 
    fread(&read_num, sizeof(int), 1, fp2); 
    fclose(fp2); 

此外,這種寫作方式不是C++方式,而是C方式。 C++文件操作的方式是指流,請參閱下面的示例:

#include <fstream> 
#include <string> 

struct data_structure { 
    std::string name; 
    std::string description; 
    int number; 

    void save(const std::string& filename) { 
     std::ofstream file(filename.c_str()); 
     file << name.c_str() << std::endl 
      << description.c_str() << std::endl 
      << number; 
    } 
    void load(const std::string& filename) { 
     std::ifstream file(filename.c_str()); 

     getline(file, name); 
     getline(file, description); 
     file >> number; 
    } 
}; 

int main() { 
    data_structure d, loaded_d; 
    d.name = "Name"; 
    d.description = "Description"; 
    d.number = 5; 

    d.save("file.out"); 
    loaded_d.load("file.out"); 

    return 0; 
} 
+0

感謝你的第一部分,它確實有效 但是至於第二部分,問題在於Description可能不止一行,可能包含換行符它裏面的角色! – Reem 2010-05-01 16:50:42