Reading from file returning glitch value

I've been going through how to use files, and discovered the read and write keywords, that are taught on this tutorial, in the section regarding binary files:
http://www.cplusplus.com/doc/tutorial/files/

And I've tried doing what that code example does, except in the end I output the char array that was read from the file to the console window:

1
2
3
4
5
6
7
8
9
10
11
12
std::streampos size;
char* memblock;

std::ifstream openFile("test.txt", std::ios::in | std::ios::binary | std::ios::ate);

size = openFile.tellg();
memblock = new char[size];

openFile.seekg(0, std::ios::beg);
openFile.read(memblock, size);

std::cout << memblock << std::endl;     //This is where I try to output to the console window 


When outputting, it will display what is in the file (which is the text "Hello World"), but at the end, it will display what appears to be an ASCII glitch of some sort:
http://i.imgur.com/UKNyIWP.jpg

What is this, exactly? And how can I alter the code in order to prevent it from happening again?

Thanks in advance :)
When you have string like "hello" this is actually stored as 6 characters. 5 characters for the letters and one extra character to mark the end of the string. The special character '\0' is used for this purpose.

In your code the memblock data only contains the letters in the file but it doesn't have the '\0' character at the end. << will print all characters until it finds a '\0' but in your code it's not there so it will continue to print whatever happens to be stored in memory after the end of the array, until it eventually comes about a '\0' character (zero byte) and stops. That is why you get all that garbage at the end.

To fix this you could make the array 1 character larger and add the '\0' character at the end.
1
2
memblock = new char[size + 1];
memblock[size] = '\0';

Another way is use the write member function so that you can pass the size as an argument without the need of a '\0' character.
 
std::cout.write(memblock, size);
I've taken note of the escape character ('\0'). I'll admit I am familiar with how it works, but it didn't come to mind that it would be the reason why a glitch was output. Thanks.

With that being said, there is a syntax error in the code you gave me:
memblock = new char[size + 1]
This cannot be done, since you can't add an object of type streampos with an int. In order to get around this, I had to declared a new streampos and initialize it to 2:
1
2
3
std::streampos size, size2 = 1;
/*Declare memblock and openFile, initialize size to the end of openFile*/
memblock = new char[size + size2];
This is the best method I could think of. Do you know of any more efficient alternatives?

Lastly, there was one thing I didn't fully understand:
use the write member function so that you can pass the size as an argument
std::cout.write(memblock, size);
I'm honestly not sure what we're trying to achieve with this line. Would you care to explain further?


Thanks for replying and for your patience :)
Registered users can post here. Sign in or register to post.