Home > OS >  Using Python to write a mix of integer and floating point numbers to a binary file read by a code in
Using Python to write a mix of integer and floating point numbers to a binary file read by a code in

Time:07-09

I have code in C which reads data from a file in a binary format:

FILE *file;
int int_var;
double double_var;
file = fopen("file.dat", "r");
fread(&int_var, sizeof(int), 1, file);
fread(&double_var, sizeof(double), 1, file);

The above is a simplified but accurate version of the actual code. I have no choice over this code or the format of this file.

The data being read in C is produced using Python code. How do I write this data to a file in the same binary format? I looked into bytes and bytearrays, but they seem to only work with integers and strings. I need something like:

f = open('file.dat', 'wb')
f.write(5)
f.write(5.0)
f.close()

that will work with the above C code.

CodePudding user response:

As mentioned in a comment, you need the struct library:

Creating file.dat with

#!/usr/bin/env python3                                                                                                                                                                                                                           
import struct
with open('file.dat', 'wb') as f:
    f.write(struct.pack('=id', 1, 5.0))

and then reading it with

#include <stdio.h>

int main(void) {
  int int_var;
  double double_var;

  FILE *file = fopen("file.dat", "rb");
  if (!file) {
    fprintf(stderr, "couldn't open file.dat!\n");
    return 1;
  }

  if (fread(&int_var, sizeof(int), 1, file) != 1) {
    fprintf(stderr, "failed to read int!\n");
    return 1;
  }

  if (fread(&double_var, sizeof(double), 1, file) != 1) {
    fprintf(stderr, "failed to read double!\n");
    return 1;
  }

  printf("int = %d\ndouble = %f\n", int_var, double_var);

  fclose(file);
  return 0;
}

will output

int = 1
double = 5.000000

Note the = in the pack format definition; that tells python not to add alignment padding bytes like you'd get in a C structure like

struct foo {
  int int_var;
  double double_Var;
};

Without that, you'll get unexpected results reading the double in this example. You also have to worry a little bit about endianess if you want the file to be portably read on any other computer.

  • Related