Tag Archives: I/O

How to read a file into a string in C++

Method

  1. Open the file
  2. Seek to the end and use tell to find out how big it is
  3. Seek back to the beginning
  4. Construct a string with the length + 1 and fill it with nul characters so it’s nul-terminated
  5. Read the contents into the string’s buffer

You can do this using iostreams or stdio.

Using iostreams

    std::ifstream in(filename);
    if (in) {
        in.seekg(0, std::ios::end);
        size_t len = in.tellg();
        in.seekg(0);
        std::string contents(len + 1, '\0');
        in.read(&contents[0], len);
    }

Using stdio

    std::FILE* fptr = std::fopen(filename.c_str(), "r");
    if (fptr) {
        std::fseek(fptr, 0, SEEK_END);
        size_t len = std::ftell(fptr);
        std::fseek(fptr, 0, SEEK_SET);
        std::string contents(len + 1, '\0');
        std::fread(&contents[0], 1, len, fptr);
        fclose(fptr);
    }

Related

How to list the Files in a Directory in C++

C++ stream synchronization

By default, C++ standard I/O streams are synchronized with their C counterparts.
What this means is that calls to C++ steams are directly forwarded to the corresponding C stream without any buffering in the C++ stream.

For example, given FILE pointers called fin and fout, a std::istream called is, and a std::ostream called os, the following calls are equivalent:

std::fputc(fout, c) and os.rdbuf()->sputc(c)
std::fgetc(fin) and is.rdbuf()->sbumpc()
std::ungetc(c, fin) and is.rdbuf()->sputbackc(c)

This allows calls to C and C++ I/O functions to be intermixed freely with predictable results. For example, consider the following program:

#include <iostream>
#include <cstdio>

int main()
{
    std::cout << "Wynken, Blynken, and Nod one night\n";
    printf("Sailed off in a wooden shoe -\n");
    std::cout << "Sailed on a river of crystal light,\n";
    printf("Into a sea of dew.\n");
}

This produces the following output:

Wynken, Blynken, and Nod one night
Sailed off in a wooden shoe -
Sailed on a river of crystal light,
Into a sea of dew.

This synchronization means that the expected output is produced, but can severely impact performance.
You can improve the performance of C++ streams, at the expense of foregoing being able to intermix them with C I/O functions by disabling synchronization with the std::ios_base::sync_with_stdio function:

#include <iostream>

std::ios::sync_with_stdio(false);

To illustrate what I mean about foregoing being able to intermix C++ streams with C I/O, here is the result of the program above on my system when I disable synchronization:

Sailed off in a wooden shoe -
Into a sea of dew.
Wynken, Blynken, and Nod one night
Sailed on a river of crystal light,