Reading file one Byte at a time

closed account (Lv0f92yv)
Hello, I have reviewed the section on file input/output, and am currently trying to read a file one byte at a time, change that byte, and put it back in. I am having some problems, however.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int main()

{
	ifstream inFile;
	ifstream::pos_type size;

	inFile.open( "test.txt", ios::in|ios::binary|ios::ate );
	char* oData;

	size = inFile.tellg();
	cout << "Size of file: " << size;
	inFile.seekg(0, ios::beg);

	oData = new char[ size ];

	inFile.read( oData, size );

	cout << " oData size: " << strlen(oData);
	cout << "\n";

	//print data
	for ( int i = 0; i < strlen(oData); i++ )
	{
		cout << "oData["<<i<<"] " << oData[i];
		cout << "\n";
		cout << oData[i] << " + 'a' = " << ( oData[i] + (char)'a' );
		cout << "\n\n";

	}
getchar();
return 0;
}


I am simply adding a char (a) to each byte in the oData array.

The size variable reports a size that is different than the strlen(oData). Why is this?

I have seen example code (that will not compile with MSVC++ express 08) that uses file.get() and file.put() methods to get a byte and put a byte. That seemed to get the results I was looking for.

*I know I am supposed to check the file is actually open, but for the sake of brevity I've omitted it - I make sure the file is there (and not corrupt) before running the program. That is not an issue in this example.
Last edited on
Hey,

I corrected your code a little bit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <fstream>
#include <cstring> // for std::strlen
#include <cstddef> // for std::size_t -> is a typedef on an unsinged int

using namespace std ;

int main()
{
	ifstream inFile;
	size_t size = 0; // here

	inFile.open( "test.txt", ios::in|ios::binary|ios::ate );
	char* oData = 0;
	
	inFile.seekg(0, ios::end); // set the pointer to the end
	size = inFile.tellg() ; // get the length of the file
	cout << "Size of file: " << size;
	inFile.seekg(0, ios::beg); // set the pointer to the beginning

	oData = new char[ size+1 ]; //  for the '\0'
	inFile.read( oData, size );
	oData[size] = '\0' ; // set '\0' 
	cout << " oData size: " << strlen(oData) << "\n";

	//print data
	for ( size_t i = 0; i < strlen(oData); i++ )
	{
		cout << "oData["<<i<<"] " << oData[i];
		cout << "\n";
		cout << oData[i] << " + 'a' = " << ( oData[i] + 'a' );
		cout << "\n\n";

	}
	getchar();
	return 0;
}


Is it this what you wanted ?

closed account (Lv0f92yv)
I compiled and ran this code, and I now have consistent size prints for filesize and size of my oData array. I think the key line may have been:

oData = new char[ size+1 ]; // for the '\0'

Didn't think of that. I also noticed, after reading the documentation on this site, that line 16 is not needed when you call open( ... ) with ios::ate - this positions the pointer at the end of file, and tellg() will return its position. Though this is probably good practice to use that call anyway, in case someone modifies the open() parameters.

However, during the hours I spent outside of this, I was able to get get() and put() to work - reading one byte at a time until fail() returned true (end of file I suppose).

Is there an advantage of using one over the other?

Thanks for the reply.
Last edited on
Topic archived. No new replies allowed.