简体   繁体   中英

Reading a binary file in c++ with stringstream

I want to write/read data from a file. Is it possible to divide the file (inside the code) in multiple Strings/Sections? Or read data untill a specific line?

Just like: "Read the Data untill line 32, put it inside a String, read the next 32 lines and put it into another string"

Im already know how to read and find data with seekp but i dont really like it because my code always gets to long.

I already found some code but i dont understand it how it works:

dataset_t* DDS::readFile(std::string filename)
{
dataset_t* dataset = NULL;

std::stringstream ss;
std::ifstream fs;
uint8_t tmp_c;

try
{
    fs.open(filename.c_str(), std::ifstream::in);

    if (!fs)
    {
        std::cout << "File not found: " << filename << std::endl;
        return NULL;
    }

    while(fs.good())
    {
        fs.read((char*)&tmp_c, 1);
        if (fs.good()) ss.write((char*)&tmp_c, 1);
    }
    fs.close();

    dataset = new dataset_t();

    const uint32_t bufferSize = 32;
    char* buffer = new char[bufferSize];

    uint32_t count = 1;
    while(ss.good())
    {
        ss.getline(buffer, bufferSize);

        dataitem_t dataitem;
        dataitem.identifier = buffer;
        dataitem.count = count;
        dataset->push_back(dataitem);

        count++;
    }

    return dataset;
}
catch(std::exception e)
{
    cdelete(dataset);
    return NULL;
}

}

The Code edits a binary save file.

Or can someone link me a website where i can learn more about buffers and stringstreams?

You could create some classes to model your requirement: a take<N> for 'grab 32 lines', and a lines_from to iterate over lines.

Your lines_from class would take any std::istream : something encoded, something zipped, ... as long as it gives you a series of characters. The take<N> would convert that into array<string, N> chunks.

Here's a snippet that illustrates it:

int main(){
    auto lines = lines_from{std::cin};

    while(lines.good()){
        auto chunk = take<3>(lines);
        std::cout << chunk[0][0] << chunk[1][0] << chunk[2][0] << std::endl;
    }
}

And here are the supporting classes and functions:

#include <iostream>
#include <array>

class lines_from {
public:
    std::istream &in;
    using value_type = std::string;

    std::string operator*() {
        std::string line;
        std::getline(in, line);
        return line;
    }

    bool good() const {
        return in.good();
    }
};

template<int N, class T>
auto take(T &range){
    std::array<typename T::value_type, N> value;
    for (auto &e: value) { e = *range; }
    return value;
}

(demo on cpp.sh )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM