Thread: Help with Reading and writing binary data

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    224

    Help with Reading and writing binary data

    I have the following code which reads and writes binary data:
    Code:
    #include <stdio.h>
    
    typedef struct foo_struct
    {
     int a;
     int b;
     int *c;
    } foo;
    
    int main()
    {
     foo *test = (foo *) malloc(sizeof(foo));
     FILE *file = fopen("bin.dat", "w");
     int i;
    
     test->a = 5;
     test->b = 2;
     test->c = (int *) malloc(sizeof(int) * 4);
     test->c[0] = 7778;
     test->c[1] = 88887;
     test->c[2] = 9877;
     test->c[3] = 178870;
    
     fwrite(test, sizeof(foo), 1, file);
     fclose(file);
     free(test->c);
     free(test);
     test = (foo *) malloc(sizeof(foo));
    
     file = fopen("bin.dat", "r");
     fread(test, sizeof(foo), 1, file);
    
     printf("a: %i\n", test->a);
     printf("b: %i\n", test->b);
     
     for(i = 0; i < 4; i++)
      printf("c[%i]: %i\n", i, test->c[i]);
    
     fclose(file);
    
     return 0;
    }
    This runs fine, but I'm not convinced this works. Do I have to allocate memory for test->c before the call to fread()? If so, how would I read in binary data if c was an indeterminate length? Is there something similar to Java's serialization?

    Thanks,
    Yasir

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >FILE *file = fopen("bin.dat", "w");
    >file = fopen("bin.dat", "r");
    "wb" and "rb", respectively. Your code will work on machines that don't differentiate between text and binary, but it's not portable.

    >Do I have to allocate memory for test->c before the call to fread()?
    No. fwrite only copied the contents of the pointer, not the contents of the memory pointed to. So the code will work, and it's valid, but it won't do what you want because the address you read from the file won't be meaningful. When you have a structure with pointer fields, you really have no choice but to write the contents of the memory manually. Bitwise I/O won't work with pointers because it does what is called a shallow copy.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Sep 2003
    Posts
    224
    So in shallow copying, temp->c will have the same address as before. But obviously this is a problem because the contents at the address pointed to before may be different. How would I get around this? Go through the array and print out each value seperately?

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >How would I get around this?
    You have to do your own deep copy by either writing each value individually, or packing the structure into some form that can be retrieved easily:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct test {
      int a;
      int b;
      int *c;
    };
    
    static int pack_buf[4];
    
    void pack(struct test *st)
    {
      pack_buf[0] = st->a;
      pack_buf[1] = st->b;
      pack_buf[2] = st->c[0];
      pack_buf[3] = st->c[1];
    }
    
    void unpack(struct test *st)
    {
      st->a = pack_buf[0];
      st->b = pack_buf[1];
      st->c[0] = pack_buf[2];
      st->c[1] = pack_buf[3];
    }
    
    void test_write(const char *filename)
    {
      FILE *out = fopen(filename, "wb");
      struct test t = {123, 456, NULL};
    
      t.c = malloc(2 * sizeof *t.c);
      t.c[0] = 10;
      t.c[1] = 20;
    
      pack(&t);
      fwrite(pack_buf, sizeof(int), 4, out);
    
      fclose(out);
    }
    
    void test_read(const char *filename)
    {
      FILE *in = fopen(filename, "rb");
      struct test t;
    
      t.c = malloc(2 * sizeof *t.c);
      fread(pack_buf, sizeof(int), 4, in);
      unpack(&t);
    
      printf("%d -- %d -- [%d,%d]\n", t.a, t.b, t.c[0], t.c[1]);
    
      fclose(in);
    }
    
    int main(void)
    {
      test_write("file.txt");
      test_read("file.txt");
    
      return 0;
    }
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Oddities reading binary data
    By KingCandyCorn in forum C Programming
    Replies: 6
    Last Post: 02-15-2009, 05:47 PM
  2. Binary Tree - Reading From and Writing to a File
    By Ctank02 in forum C++ Programming
    Replies: 2
    Last Post: 03-15-2008, 09:22 PM
  3. accessing my com port, writing and reading data
    By shoobsie in forum C Programming
    Replies: 7
    Last Post: 09-16-2005, 03:29 PM
  4. Reading binary files and writing as text
    By thenrkst in forum C++ Programming
    Replies: 8
    Last Post: 03-13-2003, 10:47 PM
  5. Replies: 2
    Last Post: 12-16-2001, 09:09 PM