# ifstream problem (solved)

## Recommended Posts

YellowMaple    174
Hi, I'm having some issues with reading from a file:
	VertexShader CreateVertexShader(const char* source)
{
std::ifstream file;
size_t size;
char* buffer;

file.open(source, std::ios_base::in);
if(!file.good())
{
file.close();
return 0;
}

file.seekg(0, std::ios::end);
size = file.tellg();
file.clear();
file.seekg(0, std::ios::beg);
buffer = new char[ size + 1 ];
buffer[ size ] = 0;
file.close();
// ...
}


The problem is that after the file.read call, my buffer is filled with the contents of my file. It looks good for the most part, except at the end there's a bunch of garbage characters: ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ The file I'm reading from is just a plain text file:
attribute vec4 inPosition;
// attribute vec3 inNormal;
// attribute vec2 inTexCoord0;
// attribute vec2 inTexCoord1;
// attribute vec2 inTexCoord2;

uniform mat4 WorldView;
uniform mat4 Projection;

// varying vec3 Normal;
// varying vec3 Diffuse;
// varying vec3 Specular;

void main()
{
gl_Position = Projection * WorldView * inPosition;
// Normal = normalize(gl_NormalMatrix * gl_Normal);
// TexCoord = TexCoord0.st;
}


The buffer looks good all the way up until the closing } bracket for the main function. I'm using Visual Studio 2008 express and the text file was created in Notepad++. Thanks! [Edited by - Zahlman on May 1, 2010 9:28:21 PM]

##### Share on other sites
YellowMaple    174
I guess I just needed a bit more time; it seems that you need to pass in std::ios_base::binary when opening the file on windows!

##### Share on other sites
Zahlman    1682
Quote:
 Original post by YellowMapleI guess I just needed a bit more time; it seems that you need to pass in std::ios_base::binary when opening the file on windows!

This does not depend on your system. Use the binary mode for a file that must be interpreted as "raw". Use the text mode for a file for which you want to perform line-feed conversions and interpret the system end-of-file character (ASCII 26 on Windows, 4 on Linux) as actually marking the end of the file.

The real problem is that your seeking trick is actually not reliable for determining the length of a file. Instead, you should use modern C++ standard library tools, which avoid the need to know the length of the file.

There are a lot of things you can simplify here. In particular, you do not need to close the file explicitly due to RAII.

BTW, why do you "return 0" to indicate an error here? VertexShader looks like the name of a class. If so, this would call a VertexShader(int) constructor and return the result. Almost certainly not what you want. This is a good fit for using an exception instead. In the code below, I use the standard library to throw an exception implicitly if anything goes wrong with reading the file.

VertexShader CreateVertexShader(const std::string& file_name){	std::ifstream file;	file.exceptions(std::ios::badbit | std::ios::failbit);	file.open(file_name);	// istream_iterator and back_inserter come from <iterator>	typedef std::istream_iterator<char> iterator;	// The extra parentheses are needed here to prevent the compiler from	// interpreting this as a function definition. This is the so-called 	// "most vexing parse" should you care to look up more information.	std::string file_contents((iterator(file)), iterator());	// ...}