Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Opening a binary file in MS Visual C++

Posted on 2004-09-05
14
Medium Priority
?
258 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

721 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