簡體   English   中英

在C ++中讀寫二進制文件

[英]Reading and writing to binary file in C++

我需要制作一個包含“名稱”的文件,該文件是一個字符串-char數組-和“數據”這是字節數組-在C ++中是char數組-但是我遇到的第一個問題是如何分隔“名稱”從“數據”? 在這種情況下,可以使用換行符(假設名稱中沒有“ \\ n”),但是在“數據”部分中可以包含特殊字符,因此無法知道何時結束,因此我將文件中的int值,該數據在具有“數據”大小的數據之前! 我嘗試使用以下代碼來做到這一點:

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函數,我得到了6次輸出(最后一次獲得每個字段為空字段),而我只寫了5次! 有人知道為什么嗎? while(!filestr.eof())嗎?

感謝幫助

首先,您以二進制格式進行的寫入/讀取應該像這樣工作(在此讀取序列之后, 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;
}

好吧,您的代碼存在一些問題:

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);

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

解決此問題后,請查看您的代碼是否有效。 通過更正這些呼叫,當然可以更輕松地進行故障排除。 :)

另外,如果您打算使用字段長度(以int形式寫入文件),則需要設置某種系統來讀取長度,然后讀取數據,並且每個長度都應該有一個長度領域。 使用類絕對是處理該問題的最簡單方法。

編輯:您可能想使用結構和函數而不是類,或者可以將類與方法一起使用。 並不重要,兩者都很簡單。 結構/ 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM