Reading files using ifstream.read(buf, length) - receiving corrupted data (most of the time)

Viewed 36

I'm currently learning C++ and OpenGL. Now I'm trying to read a complete file into a C style string (to be precise, the file I'm trying to read contains the source code for a GLSL shader).

Suppose the following code:

std::streamoff get_char_count(const char *path) {
    auto file = std::ifstream(path);
    file.seekg(0, std::ios::end);
    return file.tellg();
}

char *read_all_text(const char *path) {
    auto file_size = get_char_count(path);
    auto file = std::ifstream(path);
    auto buf = new char[file_size];
    file.read(&buf[0], file_size);
    return buf;
}

File content:

#version 330 core
out vec4 color;

void main() {
    color = vec4(0.35, 0.35, 1, 1);
}

Calling read_all_text(), I would expect to receive the file contents exactly as described above. However, I am getting the file content, plus in most cases, some garbled appendage:

#version 330 core
out vec4 color;

void main() {
    color = vec4(0.35, 0.35, 1, 1);
}
ar

I suspect that I'm accidentally reading into adjacent memory. However, looking at the source of get_char_count(), I'd expect to be given the correct count of characters in the file - I confirmed the characters in the file to be ASCII-characters only.

Is there something obvious that I'm missing?

PS: I'd prefer to stay with the char[] buffer approach, since it appears to be the most efficient option (as opposed to using iterators or rdbuf).

1 Answers

You have to null-terminate the C string. The file has no '\0' at the end, so it is not read from the field, but a C string must be terminated with '\0':

auto buf = new char[file_size + 1];
file.read(buf, file_size);
buf[file_size] = '\0';
Related