2016-06-20 11 views
1

私はFORTRAN 77バイナリファイル(ビッグエンディアンのSun Sparcマシンで作成)を持っています。私は私のリトルエンディアンマシンでそれを読んでみたい。私はこのcまたはC++でFORTRANバイナリファイルを読む方法は?

http://paulbourke.net/dataformats/reading/

に遭遇してきたポールは、CまたはC++のためにこれらのマクロを書いていますが、私は彼らが本当に何をすべきか理解していません。

#define SWAP_2(x) ((((x) & 0xff) << 8) | ((unsigned short)(x) >> 8)) 
#define SWAP_4(x) (((x) << 24) | (((x) << 8) & 0x00ff0000) | \ 
     (((x) >> 8) & 0x0000ff00) | ((x) >> 24)) 
#define FIX_SHORT(x) (*(unsigned short *)&(x) = SWAP_2(*(unsigned short *)&(x))) 
#define FIX_LONG(x) (*(unsigned *)&(x) = SWAP_4(*(unsigned *)&(x))) 
#define FIX_FLOAT(x) FIX_LONG(x) 

は、私は、ファイルのすべてのレコードが含まれているiは整数* 2である

x,y,z,t,d,i 

含まれ、他のすべての変数* 4本物であることを知っています。 まず512バイトhexdumpが

0000000 0000 1800 0000 0000 0000 0000 0000 0000 
0000010 0000 0000 0000 0000 ffff ffff 0000 1800 
0000020 0000 1800 003f 0000 0000 0000 233c 0ad7 
0000030 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000040 0000 1800 803f 0000 0000 0000 233c 0ad7 
0000050 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000060 0000 1800 c03f 0000 0000 0000 233c 0ad7 
0000070 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000080 0000 1800 0040 0000 0000 0000 233c 0ad7 
0000090 0000 0000 233c 0ad7 0000 0100 0000 1800 
00000a0 0000 1800 2040 0000 0000 0000 233c 0ad7 
00000b0 0000 0000 233c 0ad7 0000 0100 0000 1800 
00000c0 0000 1800 4040 0000 0000 0000 233c 0ad7 
00000d0 0000 0000 233c 0ad7 0000 0100 0000 1800 
00000e0 0000 1800 6040 0000 0000 0000 233c 0ad7 
00000f0 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000100 0000 1800 8040 0000 0000 0000 233c 0ad7 
0000110 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000120 0000 1800 9040 0000 0000 0000 233c 0ad7 
0000130 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000140 0000 1800 a040 0000 0000 0000 233c 0ad7 
0000150 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000160 0000 1800 b040 0000 0000 0000 233c 0ad7 
0000170 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000180 0000 1800 c040 0000 0000 0000 233c 0ad7 
0000190 0000 0000 233c 0ad7 0000 0100 0000 1800 
00001a0 0000 1800 d040 0000 0000 0000 233c 0ad7 
00001b0 0000 0000 233c 0ad7 0000 0100 0000 1800 
00001c0 0000 1800 e040 0000 0000 0000 233c 0ad7 
00001d0 0000 0000 233c 0ad7 0000 0100 0000 1800 
00001e0 0000 1800 f040 0000 0000 0000 233c 0ad7 
00001f0 0000 0000 233c 0ad7 0000 0100 0000 1800 
0000200 

ファイル

#include <endian.h> 
#include <stdint.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    FILE *file; 
    char *buffer; 
    char *rec; 
    long fileLen; 

    file = fopen("rec.in", "rb"); 


    fseek(file, 0, SEEK_END); 
    fileLen=ftell(file); 
    fseek(file, 0, SEEK_SET); 

    buffer=(char *)malloc(fileLen+1); 

    fread(buffer, fileLen, 1, file); 
    fclose(file); 
    free(buffer); 

char *curr = buffer; 
char *end = buffer + fileLen; 

constexpr int LINE_SIZE = sizeof(float)*5 + sizeof(uint16_t); //based upon your "x,y,z,t,d,i" description 

while(curr < end) { 
    uint32_t temp = be32toh(*reinterpret_cast<uint32_t*>(*curr)); 
    float x = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+sizeof(float)))); 
    float y = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+2*sizeof(float)))); 
    float z = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+3*sizeof(float)))); 
    float t = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+4*sizeof(float)))); 
    float d = *reinterpret_cast<float*>(&temp); 

    uint16_t i = be16toh(*reinterpret_cast<uint16_t*>(*(curr+5*sizeof(float)))); 

    curr += LINE_SIZE; 

} 

} 

を読むために私のコード私は2つのエラー r.ccました:機能に ')(int型メインを':

r.cc:29:1: error: ‘constexpr’ was not declared in this scope 
constexpr int LINE_SIZE = sizeof(float)*5 + sizeof(uint16_t); //based upon your "x,y,z,t,d,i" description 
^ 
r.cc:49:13: error: ‘LINE_SIZE’ was not declared in this scope 
    curr += LINE_SIZE; 
+0

をマクロは危険であり、16ビットを有するshort' 'に頼るようないくつかの時代遅れの技術を使用しています。 – Olaf

+1

CとC++は**異なる**言語です!あなたのコードはCのように見え、** **言語を選んでください! – Olaf

+0

これは人間が読める形式がはるかに望ましい理由です。 –

答えて

1

場合あなたはLinuxマシン上のファイルを読んでいますが、endian.hヘッダーにこの目的のために提供されているライブラリ関数がいくつかあります(ドキュメントhere)。オーダーをホストする16ビット整数(あなたのケースではリトルエンディアン)に変換するには:山車のために

uint16_t hostInteger = be16toh(bigEndianIntegerFromFile); 

を、あなたは似た何かをするが、再解釈を組み込むことができます:

あなたが読めば
float hostFloat = reinterpret_cast<float>(be32toh(reinterpret_cast<uint32_t>(bigEndianFloatFromFile))); 

あるいは、

float hostFloat = reinterpret_cast<float>(be32toh(bigEndianUint32FromFile)); 

UPDATE:を考えると、あなたのタラそれが最初の場所でunsigned intとして、あなたはreinterpret_castインナーは必要ありませんeは、あなたがあなたのfclosefree呼び出しの間にこれを挿入することによって、ファイルの読み取りができます

char *curr = buffer; 
char *end = buffer + fileLen; 

constexpr int LINE_SIZE = sizeof(float)*5 + sizeof(uint16_t); //based upon your "x,y,z,t,d,i" description 

while(curr < end) { 
    uint32_t temp = be32toh(*reinterpret_cast<uint32_t*>(*curr)); 
    float x = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+sizeof(float)))); 
    float y = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+2*sizeof(float)))); 
    float z = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+3*sizeof(float)))); 
    float t = *reinterpret_cast<float*>(&temp); 

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+4*sizeof(float)))); 
    float d = *reinterpret_cast<float*>(&temp); 

    uint16_t i = be16toh(*reinterpret_cast<uint16_t*>(*(curr+5*sizeof(float)))); 

    curr += LINE_SIZE; 

    ... 
    //do something with these values 
    ... 
} 
+0

私の編集、plsを見てみましょう! – MikiBelavista

+0

OPのコードはC++ではなくCのように見えます。 – Olaf

+1

もちろん、彼はC++ストリームを使用していません。あなたはC言語ではなくC++と呼ぶことができますが、私は彼の質問を無効にするとは思いません。彼は他の場所にコードを持っている可能性があります。それははるかにC++です。私は判断しません。 – Smeeheey

関連する問題