C++: a binary Fortran file

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Cette page est une traduction de la page C++ : fichier Fortran binaire et la traduction est complétée à 100 % et à jour.

Autres langues :anglais 100% • ‎français 100%

Reading an 'unformatted' Fortran file in C++

Fortran has a rather peculiar method of writing binary files; files that are created with the form='unformatted' attribute have an internal structure which distinguishes them from the raw sequences of bytes that you can create in C/C++. With the Fortran compilers installed at Calcul Québec, each write operation saves the data along with two identical boundary fields of four bytes (eight bytes when using the PGI compiler). These boundary fields indicate the total length of the data being saved. While this format is specific to Fortran, it doesn't prevent the resulting files from being portable; the following example shows how to read binary data from a Fortran-created file in a C++ program.

Here is a snippet of Fortran code which writes a binary file:

File : unformatted.f90
parameter (length = 10)
type point
   double precision x, y, z
endtype
type(point) list(length)
...
open(80, file='test_output', form='unformatted')
write(80) length
do i=1, length
   write(80) list(i)%x, list(i)%y, list(i)%z
enddo
close(80)


Here is the C++ code which allows you to read this binary file:

File : readftn.cpp
#include <fstream>
#include <vector>
#include <string>
 
using namespace std;
 
struct Point
{
   double x, y, z;
};
 
const int RECORD_DELIMITER_LENGTH = 4;
 
bool ReadPoints(const string& fileName, vector& points)
{
   int nbPoints;
 
   // clear the points
   points.clear();
 
   // open file in binary mode
   ifstream input(fileName.c_str(), ios::binary);
 
   if (input.good())
   {
      // read number of points
      input.seekg(RECORD_DELIMITER_LENGTH, ios::cur);
      input.read((char*) &nbPoints, sizeof(nbPoints));
      input.seekg(RECORD_DELIMITER_LENGTH, ios::cur);
 
      // set vector size
      points.resize(nbPoints);
 
      // read each point
      for (int i = 0; i < nbPoints; ++i)
      {
         input.seekg(RECORD_DELIMITER_LENGTH, ios::cur);
 
         input.read((char*) &points[i].x, sizeof(points[i].x));
         input.read((char*) &points[i].y, sizeof(points[i].y));
         input.read((char*) &points[i].z, sizeof(points[i].z));
 
         input.seekg(RECORD_DELIMITER_LENGTH, ios::cur);
      }
 
      return true;
   }
   else
   {
      return false;
   }
}


Useful links:

Using C and C++ with Fortran
Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager