Sign in to follow this  
pavel989

length of a file is not right

Recommended Posts

I have :
ifstream file ("example.txt", ios::in|ios::binary|ios::ate);
	
	if (file.is_open())
	{	
		size = file.tellg();
		memblock = new char [size];
		file.seekg (0, ios::beg);
		file.read (memblock, 2);
		cout<< strlen(memblock);
		file.close();
	}
	else
	{
		cout<< "Didnt open";
	}

and example.txt simply has "poopy" written in it. without the quotes. but strlen says 24. whats it doin?

Share this post


Link to post
Share on other sites
Quote:
Original post by pavel989
and example.txt simply has "poopy" written in it. without the quotes. but strlen says 24. whats it doin?


size = file.tellg();  // returns 5
memblock = new char [size]; // allocate 5 bytes, which contain random values
file.seekg (0, ios::beg);
file.read (memblock, 2); // read 2 bytes into memblock
cout<< strlen(memblock); // search memblock for first \0


Problem is, strlen doesn't know what a word is. It considers the string to end when it encounters a \0 character, which in your case happens to be 25th byte. strlen is actually searching memory you didn't allocate.

Putting memblock[3] = 0 would solve the problem.

Of course, why you would read 2 characters when you know there are 5 characters is beyond me.

A better way:
memblock = new char [size+1];
file.seekg (0, ios::beg);
file.read (memblock, size);
memblock[size] = 0;
cout<< strlen(memblock);


Of course, that will still break if your binary file contains a \0.

Share this post


Link to post
Share on other sites
strlen counts until it hits the NUL terminator found in C style strings.

However, the file doesn't have any NULs in it. read() fills memblock... but since there's no NUL, when you call strlen on it, you get a buffer overflow -- basically, strlen keeps reading random data past the end of your array.

If you're lucky, this kind of code will crash. You were less lucky -- your program just kept on running with nary a clue in the world that something is wrong except some bad output.

This is why we tend to recommend avoiding the C string manipulation functions (strlen, strcpy, etc) and char* pointers, instead recommending the C++ std::string and std::vector<char> classes as appropriate. They manage their own memory, keep track of their own size, making it easier to avoid making mistakes.

	ifstream file ("example.txt", ios::in|ios::binary|ios::ate);

if (file.is_open())
{
file.seekg (0, ios::end);
size = file.tellg();
file.seekg (0, ios::beg);
memblock.assign( std::ifstream_iterator<char>(file), std::ifstream_iterator<char>() );
cout << memblock.size();
file.close();
}
else
{
cout<< "Didnt open";
}

Share this post


Link to post
Share on other sites
well the thing is, i plan to work on more than binary files. im kind of learning encryption on my own, just for fun.

so can i add an ending character at the end of a memory block?

the reason i put 2 in file.read() is because i'm going to work with hexadecimal values. but it doesnt seem as though it makes a difference what number i put in there. or does it?

Share this post


Link to post
Share on other sites
Quote:
Original post by pavel989
the reason i put 2 in file.read() is because i'm going to work with hexadecimal values.

Hexadecimal is just a way to represent values. 3F in hexadecimal is the same as 63 in decimal, which is the same as 00111111 in binary form. There's no difference between the actual values.

Now, of course, "3F" is a different story, because it's text. It's a row of characters. If you want to retrieve it's numerical value, you need to parse it to determine it's value. The same goes for "63" and "00111111".

Share this post


Link to post
Share on other sites
Quote:
Original post by pavel989
well the thing is, i plan to work on more than binary files. im kind of learning encryption on my own, just for fun.

so can i add an ending character at the end of a memory block?
Add block length to the beginning of the block. Your data might contain "ending character".

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this