Opening a binary file in MS Visual C++

I have a binary file with an arbitary number of unsigned Chars, representing a 3d dataset. I am looking for an example of code which will open the file and load the data into a 3d array,

Many Thanks..
chrishughesAsked:
Who is Participating?
 
drichardsCommented:
Do you need additional help then?  The above code is one approach but by no means the only one.  If you use that method, remember that arr3d or it's equivalent must be of type unsigned char (like 'unsigned char arr3d[2][3][4]', for example).
0
 
drichardsCommented:
That is not enough information to go on.  What is the format of the file?  Specifically, how is the 3d array laid out?

To open a file in binary mode, you can do:

    #include <fstream>
    ...
        std::ifstream inFile;
        infile.open(filename, std::ios_base::binary);

What you do after that depends on what exactly is in the file.  At that point you use avaliable input methods to fetch the data from the file in the apperopriate manner.
0
 
chrishughesAuthor Commented:
Hi!

Well I know the 3d data set is x * y * z, and all of the values are unsigned chars in a sequential order..

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
drichardsCommented:
So what is the ordering of the unsigned char values and how do you know the dimensions x, y, and z?  If you know the dimensions, you can create an appropriate array of unsigned char and do loops:

for ( int z = 0; z < ZDim; z++ )
{
  for ( x = 0; x < XDim; x++ )
  {
    for ( int y = 0; y < YDim; y++ )
    {
        inFile >> arr3d[z][x][y];
    }
  }
}

If you know two of the three dimensions - suppose the file is a set of 'XDim-by-YDim' layers but you don't know how many layers there are - you can change the outer loop to be "while ( !infile.eof() )" which will just keep reading layers until the file is empty.

As you see, you need to have some idea what's in the file and how the data is arranged.
0
 
chrishughesAuthor Commented:
Hi Thanks for your help! I obviously realise that I need to know the order etc of the data - I was more looking for an example of how the actul file handling is done in C++ as I have never tried this before!

:-)
0
 
rstaveleyCommented:
If the file is a list of points (i.e. a list of x,y,z coordinates), your 3D array might not be the way to go. You might be better off with a user-defined structure - e.g. struct Coord {unsigned char x,y,z;};. Then use a container for the structure. Then fill the container with the points read from the file.

e.g.
--------8<--------
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <algorithm>

struct Coord {unsigned char x,y,z;};
typedef std::vector<Coord> CoordList;
CoordList coordList;

// To display a Coord object
std::ostream& operator<<(std::ostream& os,const Coord& coord)
{
      return os << '(' << static_cast<int>(coord.x) << ',' << static_cast<int>(coord.y) << ',' << static_cast<int>(coord.z) << ')';
}

int main()
{
      std::ifstream fin("x.dat",std::ios::binary);
      Coord coord;
      while (fin.read(reinterpret_cast<char*>(&coord),sizeof(coord)))
            coordList.push_back(coord);
      std::cout << "Coords are: ";
      copy(coordList.begin(),coordList.end(),std::ostream_iterator<Coord>(std::cout,", "));
      std::cout << '\n';
}
--------8<--------
0
 
chrishughesAuthor Commented:
AHHH!!!

Ok so I have made a big mistake in my question... Basically the binary file, contains a list of 32 bit ints. I simply need an example of how to open the file, read each int at a time and output its value to the console.

Many thanks - I have increased the points due to my mistake..
0
 
rstaveleyCommented:
You need to find out if your ints are little-endian or big-endian.
0
 
rstaveleyCommented:
Conventionally ints sent over the network are sent in network byte order, which means big endian. If you are on an Intel platform, you need to convert these to little-endian, which means using the ntohl macro, which you can generally get by including <arpa/inet.h> or <netinet/in.h> (it isn't part of the standard, alas - look at your man page).

If the ints have been generated by the local machine and they've been written directly to file without conversion, you can read them directly into an unsigned long, which ought to provide you with 32 bits (though this isn't guaranteed in the standard) and you can skip the ntohl conversion.

Here's some demonstration code with the conversion macro, which assumes that your ints are in network byte order:
--------8<--------
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <algorithm>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif

typedef unsigned long Value;
typedef std::vector<Value> ValueList;
ValueList valueList;

int main()
{
     std::ifstream fin("x.dat",std::ios::binary);
     Value value;
     while (fin.read(reinterpret_cast<char*>(&value),sizeof(value)))
          valueList.push_back(ntohl(value)); // Using ntohl macro
     std::cout << "Values are: ";
     copy(valueList.begin(),valueList.end(),std::ostream_iterator<Value>(std::cout,", "));
     std::cout << '\n';
}
--------8<--------
0
 
chrishughesAuthor Commented:
Hi!

When I try to execute the above code I get the following error:

C:\work\opengl\vertex_volume\example.cpp(44) : error C2079: 'fin' uses undefined class 'basic_ifstream<char,struct std::char_traits<char> >'
C:\work\opengl\vertex_volume\example.cpp(44) : error C2078: too many initializers
C:\work\opengl\vertex_volume\example.cpp(46) : error C2228: left of '.read' must have class/struct/union type
C:\work\opengl\vertex_volume\example.cpp(46) : fatal error C1903: unable to recover from previous error(s); stopping compilation
0
 
rstaveleyCommented:
Can you try...

     std::ifstream fin("x.dat",std::ios_base::binary);
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.