Solved

Opening a binary file in MS Visual C++

Posted on 2004-09-05
14
252 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 75 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 75 total points
ID: 11990134
Can you try...

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

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
VS2015 compilation and missing DLLs 9 180
Using Diagnostic tools in VS2015: Unresoved allocations 19 122
Create a path if not exists 7 105
Adding items to a C# list incrementally 5 58
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

679 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