Question about reading from Binary I/O file

This code works fine. I don't know what I can do in order to display the entire file. As you can see the array is appended to the file. So if I run this program twice the file will have 200 random generated numbers...and the program should show 200 values, but it only displays the array size of 100. Any ideas?

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
38
39
40
41
#include <iostream>
#include <fstream>
#include<ctime>
using namespace std;

int main()
{
  const int SIZE = 100;  // Array size

  fstream binaryio; // Create stream object

  // Write array to the file
  binaryio.open("Exercise13_5.dat", ios::out | ios::app | ios::binary);
  int arr[SIZE];
  srand((unsigned)time(0));

  // Write to array
  for (int i = 0; i < SIZE; i++)
	{
		arr[i] = (rand()%1000); // Random number up to 1,000
	}

  binaryio.write(reinterpret_cast<char *>(&arr), sizeof(arr));
  binaryio.close();

  // Read array from the file
  binaryio.open("Exercise13_5.dat", ios::in | ios::binary);
  int result[SIZE];
  binaryio.read(reinterpret_cast<char *>(&result), sizeof(result));
  binaryio.close();

   // Display array
	for (int i = 0; i < SIZE; i++)
	{
		cout << result[i] << " ";
	}

  system("pause");
  return 0;
}
Last edited on
Your display loop only loops from 0 to 100.
Last edited on
Yes, I know that. How would you go about making it so it loops however big the file is?
You need to loop the read and print until you hit EOF. http://www.cplusplus.com/reference/iostream/istream/read/
I understand that. The only problem is that in order to read all of it I need to know the size binaryio.read(reinterpret_cast<char *>(&result), sizeof(result));

So I need to know the appropriate size before I can read the file, and eof() does not give the size. I've tried seekg() then tellg() to get the position, but that's not necessarily how many values are in the file. It's pretty much returning the size "bits" of the file. Is there another way of reading the file? That way I can then run a while loop until the end of file..
Last edited on
I have tried this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Read array from the file
  binaryio.open("Exercise13_5.dat", ios::in | ios::binary);
  int length;

  // get length of file:
  binaryio.seekg (0, ios::end);
  length = binaryio.tellg();

  int *result = new int [length];

   // Display array
	for (int i = 0; i < length; i++)
	{
		binaryio.read(reinterpret_cast<char *>(&result[i]), length); 
		cout << result[i] << " ";
	}
	binaryio.close();
        delete [] result;


And here is my output:
-842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -84
2150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -84215
0451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -84215045
1 -842150451 -842150451 -842150451 Press any key to continue . . .


I changed hte SIZE to 5 so when I run it the first time there are only 5 values in the file. However, the file is 25 bytes...so the length returns 25 in size. Also not sure why I'm getting the memory address instead of the actual value.
Any ideas? To make it more simple, I'm trying to read a file that may have more values than what's inserted because it's appended.
Here is what I think should change (bold text):
1
2
3
4
5
6
7
8
9
10
11
12
13
  binaryio.seekg (0, ios::end);
  length = binaryio.tellg();
  binaryio.seekg(0); //to return the file pointer to the beginning

  int *result = new int [length];

   // Display array
	for (int i = 0; i < length; i++)
	{
                //you only read one int at a time
		binaryio.read(reinterpret_cast<char *>(&result[i]), sizeof(result[i]));
		cout << result[i] << " ";
	}


Regards
Thanks for the response. However, I tried what you posted and I still get memory address problems. Not sure at all what the problem is.
Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
  binaryio.seekg (0, ios::end);
  length = binaryio.tellg() / sizeof(int);
  binaryio.seekg(0); //to return the file pointer to the beginning

  int *result = new int [length];

   // Display array
	for (int i = 0; i < length; i++)
	{
                //you only read one int at a time
		binaryio.read(reinterpret_cast<char *>(&result[i]), sizeof(result[i]));
		cout << result[i] << " ";
	}

Forgot that the file size = element size * element count, and we need element count. My bad.

Regards
Hmm..the first result is returning correct, but the rest are addresses. Also I get one warning when compiling the code. It's not liking length = binaryio.tellg() / sizeof(int);

warning C4244: '=' : conversion from 'std::streamoff' to 'int', possible loss of data


Here's code output: Also SIZE is only 5..so there should only be 5 results in the file. Underline are not correct for some reason.
389 2526412 64343040 -640942080 -872415201 415 Press any key to continue . . .
Last edited on
The following code, which I produced from applying my changed segment to the original works with me (winXP, mingw gcc 4.5.0):
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
38
39
40
41
42
43
44
45
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
  const int SIZE = 100;  // Array size

  fstream binaryio; // Create stream object

  // Write array to the file
  binaryio.open("Exercise13_5.dat", ios::out | ios::app | ios::binary);
  int arr[SIZE];
  srand((unsigned)time(0));

  // Write to array
  for (int i = 0; i < SIZE; i++)
        {
                arr[i] = (rand()%1000); // Random number up to 1,000
        }

  binaryio.write(reinterpret_cast<char *>(&arr), sizeof(arr));
  binaryio.close();

  // Read array from the file
  binaryio.open("Exercise13_5.dat", ios::in | ios::binary);
  binaryio.seekg (0, ios::end);
  int length = binaryio.tellg() / sizeof(int);
  binaryio.seekg(0); //to return the file pointer to the beginning

  int *result = new int [length];

   // Display array
        for (int i = 0; i < length; i++)
        {
                //you only read one int at a time
                binaryio.read(reinterpret_cast<char *>(&result[i]), sizeof(result[i]));
                cout << result[i] << " ";
        }

  return 0;
}

Regards
Yes, that does work. I see where I had messed up. On line 25 I had binaryio.write(reinterpret_cast<char *>(&arr[i]), SIZE);

Which was storing only one value in the array. So of course I was getting memory addresses for the rest of the indexes. The random numbers output fine now..I do still get this warning though

c:\users\kraigballa\desktop\college\isu\spring 2011\cs 182\example\binaryarrayio.cpp(36): warning C4244: 'initializing' : conversion from 'std::streamoff' to 'int', possible loss of data
It compiles silently even with
-Wall -Wextra -pedantic
on gcc. May be your library is differently implemented. Either way, a static cast to int of the result from tellg should kill the warning, unless you want to keep it as alerter.

Regards
Alright thanks for your help. I'm using Visual Studio 2010 on Windows 7. By the way what does binaryio.tellg() / sizeof(int); this do? Are you dividing it by 4 bytes as that is the size of an int..
Last edited on
Basically, yes :)
Topic archived. No new replies allowed.