2

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).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
robng
  • 38
  • 7
  • Related/dupe: [How do I read an entire file into a std::string in C++?](https://stackoverflow.com/questions/116038/) – Remy Lebeau Sep 04 '22 at 00:59
  • Not a duplicate imo, due to the problem specifically having to do with zero-termination. – robng Sep 04 '22 at 07:55
  • not *strictly* a dupe, no. But the underlying issue is the same - to get the file contents into a string, whether that be a null-terminated C string or a C++ string, it doesn't really matter. Though, a C++ string would be better/easier in this case. – Remy Lebeau Sep 05 '22 at 02:58

1 Answers1

2

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';
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Rabbid76
  • 202,892
  • 27
  • 131
  • 174