Please help with ifstream

Started by
8 comments, last by alvaro 13 years, 8 months ago
I am losing my mind over this...I don't understand whats going on here at all

can anybody please explain why I am getting all the junk at the end of buffer1?

#include <iostream>#include <fstream>using namespace std;int main(){	ifstream fin("index.html", ios_base::binary | ios_base::in);	fin.seekg(0, ios::end);	int length = fin.tellg();	fin.seekg(0, ios::beg);	char *buffer1 = new char[length];	fin.read(buffer1, length);	char buffer2[] = "12345";		char *buffer3 = "12345";	cout << buffer1 << endl;	cout << buffer1[0] << buffer1[1] << buffer1[2] << buffer1[3] << buffer1[4] << endl;	cout << buffer2 << endl;	cout << buffer3 << endl;	system("pause");	return 1;}

the file contains "12345" no spaces, no returns.
and this is the output I get:
Quote:
12345²²²²½½½½½½½½■¯■¯■¯■
12345
12345
12345
Press any key to continue . . .

how is it that buffer1 is exactly 5 bytes, AND I can print each character individually, but when I try and use cout on it, I get all kinds of junk at the end?
Advertisement
You are printing the buffer as a zero-terminated string, but you didn't put a zero to mark the end. Allocate and extra byte and write a zero to it.
but why do the other 3 cases work then?
Quote:Original post by CPPNick
but why do the other 3 cases work then?


See previous reply. Also this.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

ok, The only place I have ever seen something like this is in an MSDN example for GetOpenFileName()
I don't understand the difference between '\0' and '0' though =/
at least I have something to go on now though. Thanks, you guys are life savers.
I was about to go check into the looney bin..lol
'0' is the character 0, which has the ASCII value 48. '\0' is a null which has the ASCII value 0.
Moving to FB

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

The program above was just a test project.

The exact problem I was having was because ifstream::read(test, 5) doesn't add a terminating '/0'

and basic_string::append() takes "C-strings" which can be defined as:

"Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string"

http://msdn.microsoft.com/en-us/library/69ze775t%28VS.80%29.aspx

therefore this did not work properly:

test.append(test);

rather than allocate extra space though, I used the second optional argument of append() to specify a number of characters to copy, since append() would not otherwise know where to stop without the terminating '\0'

test.append(test, 5);

This was part of a web server, and for the HTTP response body, the web browser doesn't expect '\0' terminated strings. That is another reason I chose not to allocate the extra byte.

[Edited by - CPPNick on July 23, 2010 9:38:03 AM]
Quote:Original post by Washu
Moving to FB


didn't know you could move it to facebook, jk.
Edge cases will show your design flaws in your code!
Visit my site
Visit my FaceBook
Visit my github
Quote:Original post by CPPNick
The exact problem was happening because ifstream::read(test, 5) doesn't add a terminating '/0'

and basic_string::append() takes "C-strings" which can be defined as:

"Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string"

http://msdn.microsoft.com/en-us/library/69ze775t%28VS.80%29.aspx

therefore this did not work properly:

test.append(test);


The code you posted didn't have any of that. The only thing you were doing with it was calling `operator<<(std::ostream&,char*>', which requires the terminating '\0' as I said.

Quote:This was part of a web server, and for the HTTP response body, the web browser doesn't expect '\0' terminated strings. That is another reason I chose not to allocate the extra byte.

Even if you use C-style zero-terminated strings, it doesn't mean that you will write those zeros in the HTTP response. The functions that take those strings as inputs will take the zero as a stopping mark and will not process them.

The program you posted has a memory leak. Be sure to delete[] the buffer when you are done with it.

The short story is that you should use std::string as much as possible.

EDIT: A couple more things. Most of the time, it makes sense to process text files line by line, and you can use std::getline(std::ifstream&,std::string&) to read them in. If you still want to read the whole file in one go, this method avoids making unnecessary copies:
std::istreambuf_iterator<char> b(my_ifstream), e;std::string content(b, e);




[Edited by - alvaro on July 23, 2010 7:12:37 AM]

This topic is closed to new replies.

Advertisement