Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Opening a binary file in MS Visual C++

Posted on 2004-09-05
14
Medium Priority
?
263 Views
Last Modified: 2013-12-14
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..
0
Comment
Question by:chrishughes
  • 4
  • 4
  • 3
14 Comments
 
LVL 19

Expert Comment

by:drichards
ID: 11985937
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
 

Author Comment

by:chrishughes
ID: 11986204
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
 
LVL 19

Expert Comment

by:drichards
ID: 11986293
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:chrishughes
ID: 11986305
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
 
LVL 19

Accepted Solution

by:
drichards earned 300 total points
ID: 11986670
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 11988630
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
 

Author Comment

by:chrishughes
ID: 11988954
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 11989007
You need to find out if your ints are little-endian or big-endian.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 11989106
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
 

Author Comment

by:chrishughes
ID: 11989755
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
 
LVL 17

Assisted Solution

by:rstaveley
rstaveley earned 300 total points
ID: 11990134
Can you try...

     std::ifstream fin("x.dat",std::ios_base::binary);
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

886 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question