簡體   English   中英

C++ 逐字符讀取二進制文件

[英]C++ read binary file char by char

我有一個任務是按照其數據成員的特定順序保存一些對象數據,我會盡量簡化。 考慮二進制文件中的這個 Base class 構造函數。 (請注意,使用 char * 不是我的選擇)。

Base(ifstream & in_file) {
    int n;
    in_file.read((char *)&n, sizeof(n));
    m_var = new char[n + 1];
    in_file.read(m_var, n);
    m_var[n] = '\0';
    in_file.read((char *)&m_intvar, sizeof(m_intvar));
}

它必須初始化 m_var (char *) 和另一個 integer 變量。 此代碼有效,但它需要為我分配memory保存 char * 的長度。

問題從這里開始。 我被指示不要保存字符串的大小,而是在我寫入文件的每個值之后只輸入一個\n 所以我需要一些如何讀取文件,並獲取字符串直到\n字符。

我正在考慮逐個字符地讀取字符,但找不到方法,我假設有一個 istream function 提供了它。 我認為一些類似於 function 到文本文件的>>也不錯。

在咨詢cppreference.com之后,我最終如下:

#include <fstream>
#include <iostream>
#include <cstring>

class Base
{
public:
    Base(std::istream & in_file) { // NOTE: changed to istream to allow reading from any stream not just files
        in_file.read((char *)&n, sizeof(n));
        char buffer[1024];
        in_file.get(buffer, sizeof(buffer), '\n');
        size_t gcount = in_file.gcount();
        if (in_file.get() != '\n')
        {
            throw std::runtime_error("binary string to long"); // you may want to implement a loop here using peek() to check for newline
        }
        m_var = new char[gcount];
        std::copy(buffer, buffer + gcount, m_var);
    }

    Base(int num, const char* strg)
        : n(num)
        , m_var(strdup(strg))
    {
    }

    bool operator == (const Base& rhs)
    {
        return n == rhs.n && strcpy(m_var, rhs.m_var);
    }

    void write(std::ostream& out)
    {
        out.write((char*)&n, sizeof(n));
        out.write(m_var, strlen(m_var));
        out.write("\n", 1);
    }


    int n;
    char* m_var = nullptr;

    ~Base()
    {
        delete m_var;
    }



};

int main(int, char**)
{
    Base b1(10, "Hello Word!");
    {
        std::ofstream out("testfile.bin");
        b1.write(out);
    }
    std::ifstream in("testfile.bin");
    Base b2(in);

    if (b1 == b2)
    {
        std::cout << "read ok!" << std::endl;
    }
    else
    {
        std::cout << "read failed!" << std::endl;
    }
    return 0;
}

4 年后,但我遇到了類似的問題並找到了這篇文章。 您可以像您提到的那樣通過循環讀取一個字符。

int i;
for(i=0;;i++){
    cout<<i;
    in_file.read(&buffer[i],sizeof(char));
    if buffer[i]=='\n') break; 
}

我提出的代碼的唯一問題是它保存了'\n'。 但是您可以而且應該在找到新行“\n”后將其替換為 NULL 字符“\0”。 (緩沖區[i]=='\0')

如果我弄錯了,請糾正我。

暫無
暫無

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

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