Search code examples
c++freadfseek

Unable to read the entire file correctly using fseek() and fread()


I have a file with shader source which i want to read that looks like this:

#version 460 core
layout(location = 0) in vec2 pos;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 fragColor;

uniform float rand;
out gl_PerVertex
{
  vec4 gl_Position;
  float gl_PointSize;
  float gl_ClipDistance[];
};

void main()
{
    fragColor = color * rand;
    gl_Position = vec4(pos.x + 0.5 * gl_InstanceID, pos.y, 0, 1);
}

first i find out the size of my file:

fseek(m_file, 0L, SEEK_END);
size_t size = ftell(m_file);

This returns 364. The problem is that if i just copy+paste the file content into a R"()" string and get a strlen it returns 347. After getting file size i try reading the whole file:

fseek(m_file, 0, SEEK_SET);
size_t count = fread(buffer, 1, size, m_file);

where buffer is allocated with 364 bytes. But fread returns 347 and feof(m_file) returns true. So as a result i get this: buffer content after reading a file with fread

(File explorer also shows that the file size is 364).

However, when i read the same file into a string using std::ifstream, everything works properly:

std::ifstream ifs(filename);
std::string content((std::istreambuf_iterator<char>(ifs)),
    (std::istreambuf_iterator<char>()));
auto size = content.size();

and size is equal to 347.

string content after reading a file with std::ifstream

The question is: am i doing something wrong or Windows/fseek just show the file size wrongly?


Solution

  • The difference between the two sizes is 19 which coincidencally is the number of lines in your shader.

    My guess is this has something to do with line ending conversations. Open the file as binary and the discrepency should go away.