簡體   English   中英

讀取在 C 中使用 Python struct 編寫的二進制數據

[英]Reading binary data written using Python struct in C

我正在用 Python 編寫要在 C 中讀取的二進制文件。編寫文件的(MWE)代碼是:

import struct

with open('test.bin', 'wb') as outfile:  
    outfile.write(struct.pack('didi', 1.2, 1, 1.3, 2))

當我用 C 讀取文件時,我得到亂碼數據:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char *argv[]) {
    double testdouble, testdoubletwo;
    int testint, testinttwo;

    FILE *f = fopen("test.bin", "rb");
    assert(f);

    assert(fread(&testdouble, sizeof(testdouble), 1, f));
    assert(fread(&testint, sizeof(testint), 1, f));
    assert(fread(&testdoubletwo, sizeof(testdoubletwo), 1, f));
    assert(fread(&testinttwo, sizeof(testinttwo), 1, f));

    fprintf(stderr, "testdouble: %f, testint: %d, testdouble: %f, testinttwo: %d", testdouble, testint, testdoubletwo, testinttwo);

    return 0;
}

輸出:

testdouble: 1.200000, testint: 1, testdouble: -92559641157289301412905710012271939667257667601819249288413184.000000, testinttwo: 1073007820

如果我省略了整數,它適用於這個小例子,但不適用於我正在閱讀幾十個雙打的實際問題。 其中一些(不是第一個,也不是最后一個)最終出現亂碼。

系統:Ubuntu 12.04,64位
蟒蛇:2.7.3

在您的 C 代碼中,您一項一項地讀取每一項,這意味着您沒有應用任何對齊方式。 試試這個:

outfile.write(struct.pack('=didi', 1.2, 1, 1.3, 2))

hexdump test.bin

0000000 3333 3333 3333 3ff3 0001 0000 cccd cccc
0000010 cccc 3ff4 0002 0000                    

C代碼輸出:

testdouble: 1.200000, testint: 1, testdouble: 1.300000, testinttwo: 2

如果你不改變python代碼,仍然使用'didi',然后像這樣改變c代碼:

struct D {
    double td;
    int ti;
    double td2;
   int ti2;
};


struct D d;
fread(&d, sizeof(struct D), 1, f);
fprintf(stderr, "testdouble: %f, testint: %d, testdouble: %f, testinttwo: %d", d.td, d.ti, d.td2, d.ti2);

本次在 Fedora 17 上測試,使用 python 2.7.3,gcc 4.7.2,我更喜歡定義結構。

我還應該說,可以更改 C 程序而不是 python 程序來工作。 這幾乎是完美的,除了在我的系統上 python 寫入一個 28 字節的文件,而我的 C 程序需要 32 字節。 它在沒有斷言的情況下工作。 不理想。 在 testinttwo 之后寫一個垃圾 int 可以解決這個問題。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char *argv[]) {
    typedef struct { double testdouble;
                     int testint;
                     double testdoubletwo;
                     int testinttwo;
                } teststruct;
    teststruct abc;
    FILE *f = fopen("test.bin", "rb");
    assert(f);
/*  assert(fread(&abc, sizeof(teststruct), 1, f));*/
    printf("sizeof(teststruct) %d\n",sizeof(teststruct));
    fread(&abc, sizeof(teststruct), 1, f);

    fprintf(stderr, "testdouble: %f, testint: %d, testdouble: %f, testinttwo: %d", abc.testdouble, abc.testint, abc.testdoubletwo, abc.testinttwo);

    fclose(f);
    return 0;
}

調整了 python 程序以修復斷言問題。

import struct

with open('test.bin', 'wb') as outfile:
    outfile.write(struct.pack('didii', 1.2, 1, 1.3, 2,0))

C輸出:

sizeof(teststruct) 32
testdouble: 1.200000, testint: 1, testdouble: 1.300000, testinttwo: 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM