Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ fread() into a std::string

Like always, problems with pointers. This time I am trying to read a file (opened in binary mode) and store some portion of it in a std::string object. Let's see:

FILE* myfile = fopen("myfile.bin", "rb");
if (myfile != NULL) {
    short stringlength = 6;
    string mystring;
    fseek(myfile , 0, SEEK_SET);
    fread((char*)mystring.c_str(), sizeof(char), (size_t)stringlength, myfile);
    cout << mystring;
    fclose(myfile );
}

Is this possible? I don't get any message. I am sure the file is O.K. When I try with char* it does work but I want to store it directly into the string. Thanks for your help!

like image 523
ali Avatar asked Nov 28 '12 18:11

ali


People also ask

Can you use std::string in C?

A std::string_view can refer to both a C++ string or a C-string. All that std::string_view needs to store is a pointer to the character sequence and a length. std::string_view provides the same API that std::string does, so it is a perfect match for C-style string literals.

What fread() does?

The fread() function reads up to count items of size length from the input stream and stores them in the given buffer. The position in the file increases by the number of bytes read.

How fread works in C++?

The fread() function reads count number of objects, each of size size bytes from the given input stream. It is similar to calling fgetc() size times to read each object. According to the number of characters read, the file position indicator is incremented.

What is using std::string?

C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.


2 Answers

Set the string to be large enough first to avoid buffer overrun, and access the byte array as &mystring[0] to satisfy const and other requirements of std::string.

FILE* myfile = fopen("myfile.bin", "rb");
if (myfile != NULL) {
    short stringlength = 6;
    string mystring( stringlength, '\0' );
    fseek(myfile , 0, SEEK_SET);
    fread(&mystring[0], sizeof(char), (size_t)stringlength, myfile);
    cout << mystring;
    fclose(myfile );
}

There are many, many issues in this code but that is a minimal adjustment to properly use std::string.

like image 129
Potatoswatter Avatar answered Sep 18 '22 20:09

Potatoswatter


I would recommend this as the best way to do such a thing. Also you should check to make sure that all the bytes were read.

    FILE* sFile = fopen(this->file.c_str(), "r");

    // if unable to open file
    if (sFile == nullptr)
    {
        return false;
    }

    // seek to end of file
    fseek(sFile, 0, SEEK_END);

    // get current file position which is end from seek
    size_t size = ftell(sFile);

    std::string ss;

    // allocate string space and set length
    ss.resize(size);

    // go back to beginning of file for read
    rewind(sFile);

    // read 1*size bytes from sfile into ss
    fread(&ss[0], 1, size, sFile);

    // close the file
    fclose(sFile);
like image 37
Mitchell Findley Avatar answered Sep 17 '22 20:09

Mitchell Findley