drreg24
drreg24

Reputation: 1

How do I read and print a binary file in C?

I'm struggling reading and printing from a binary file. Below you can see the code with main function. I was able to implement the write function, but struggling with the read part where I want to read from and print the binary file that was created.

Happy for every answer and help!

#include<stdio.h>

struct Person
{
  char name[40];
  int  age;
};

void read()
{
    puts("help");
}

void write()
{
  struct Person ps[] = { {"Tom", 25}, {"Adam", 35} };

  FILE *fo = fopen("1.bin", "wb");

  fwrite(ps, sizeof(struct Person), 2, fo);
  fwrite(ps, sizeof(ps), 1, fo);

  fclose(fo);
}

int main(int argc, char *argv[])
{
  switch(argv[1][0])
  {
    case 'w':
      puts("w");
      write();
      break;
    case 'r':
      puts("r");
      read();
      break;
    default:
      puts("Error in command line");
  }

  return 0;
} 

Upvotes: 0

Views: 929

Answers (1)

user9706
user9706

Reputation:

I renamed your functions with a "person_" prefix as not to conflict with standard functions (if you ever want to use those in your program). Implemented person_read() but passing a pointer and count n. Alternatively, person_write() could write an initial record count. You could also implement a function that counts number of records in your file, or insist on person_read() allocating a suitable array on the heap and return a pointer. You could also read a record at a time till EOF but that is more a design change. Fixed the segfault if you were not specifying any arguments. Check for errors of fopen(), fread() and fwrite(). Consider using an unsigned (char) for age instead of an int.

#include <errno.h>
#include <stdio.h>
#include <string.h>

#define NAME_LEN 40
#define PATH "1.bin"

struct Person {
    char name[NAME_LEN];
    int age;
};

void person_print(struct Person *ps, unsigned n) {
    for(unsigned i = 0; i < n; i++) {
        printf("name: %s, age; %d\n", (ps+i)->name, (ps+i)->age);
    }
}

void person_read(struct Person *ps, unsigned n) {
    FILE *fo = fopen(PATH, "rb");
    if(!fo) {
        printf("fopen failed: %s\n", strerror(errno));
        return;
    }
    if(fread(ps, sizeof(struct Person), n, fo) != n) {
        printf("fread failed: %s\n", strerror(errno));
    }
    fclose(fo);
}

void person_write(struct Person *ps, unsigned n) {
    FILE *fo = fopen(PATH, "wb");
    if(!fo) {
        printf("fopen failed: %s\n", strerror(errno));
        return;
    }
    if(fwrite(ps, sizeof(struct Person), n, fo) != n) {
        printf("fwrite failed: %s\n", strerror(errno));
    }
    fclose(fo);
}

int main(int argc, char *argv[]) {
    switch(argc > 1 ? argv[1][0] : '\0') {
        case 'r': {
            struct Person ps[2];
            person_read(ps, sizeof(ps) / sizeof(*ps));
            person_print(ps, sizeof(ps) / sizeof(*ps));
            break;
        }
        case 'w': {
            struct Person ps[] = { {"Tom", 25}, {"Adam", 35} };
            person_write(ps, sizeof(ps) / sizeof(*ps));
            break;
        }
        default:
            puts("Error in command line");
    }
    return 0;
}

Upvotes: 2

Related Questions