简体   繁体   中英

Reading data from a binary file in C

I am new to C and trying to write some data into a binary file and read from it. There are character arrays and integers as the members of structure. When I run my code and open the binary file through notepad, I can only see the strings are being read by the program. Here is my code:

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

typedef struct{
    unsigned int sample_offset;
    char receiver_name[20];
    double sample_rate;
    unsigned int channel;
    unsigned int bits;
    char file_type[11];
    unsigned int freq_band;
    double channel_bandwidth;
    double firmwire_version;
    double header_version;
}sampleInfo;

int main(){
    // Writing into the file
    FILE * fw;
    sampleInfo data = {64, "Gadfly", 51.2, 2, 4, "Spreadsheet", 1,24, 1.0,1.0 }, read_data;

    fw = fopen("test.bin","wb"); 
    if (!fw)
    {
        printf("Unable to open the file\n");
        exit(1);
    }
    else{
        fprintf(fw,"Sample offset: %u bytes\n\n", data.sample_offset)
        fprintf(fw,"Receiver's name: %s\n\n", data.receiver_name);
        fprintf(fw,"Sample rate: %.2lf Mega-samples per second\n\n", data.sample_rate);
        fprintf(fw,"Number of channels used: %u\n\n", data.channel);
        fprintf(fw,"Number of bits per I and Q sample: %u\n\n", data.bits);
        fprintf(fw,"File type: %s\n\n", data.file_type);
        fprintf(fw,"Frequency band per channel: L%u\n\n",data.freq_band);
        fprintf(fw,"Channel Bandwidth: %.1lfMHz\n\n", data.channel_bandwidth);
        fprintf(fw,"Firm-wire version: %.1lf\n\n",data.firmwire_version);
        fprintf(fw,"Header version: %.1lf\n\n",data.header_version);
    }
    fwrite(&data,sizeof(sampleInfo),1, fw); 
    fclose (fw); 

    // Reading from the file
    FILE * fr;
    fr = fopen("test.bin", "rb"); 
    if (! fr){
        printf("Unable to open the file\n");
        exit(1);
    }
    else
    {
        fread(&read_data,sizeof(sampleInfo),1, fr); 
        fscanf(fr,"Sample offset: %u bytes\n", &(read_data.sample_offset));
        fscanf(fr,"Receiver's name: %s\n", read_data.receiver_name);
        fscanf(fr,"Sample rate: %lf Mega-samples per second\n", &(read_data.sample_rate));
        fscanf(fr,"Number of channels used: %u\n", &(read_data.channel));
        fscanf(fr,"Number of bits per I and Q sample: %u\n",&(read_data.bits));
        fscanf(fr,"File type: %s\n", read_data.file_type);
        fscanf(fr,"Frequency band per channel: L%u\n", &(read_data.freq_band));
        fscanf(fr,"Channel Bandwidth: %lf MHz\n", &(read_data.channel_bandwidth));
        fscanf(fr,"Firm-wire version: %lf\n", &(read_data.firmwire_version));
        fscanf(fr,"Header version: %lf\n\n\n", &(read_data.header_version));
    }
    fclose(fr); 
    return 0;
}

And this is what I am getting as output:

Output

I can't figure out why the program is showing only the print statements as output and not reading all the data from the file properly. I have tried using the fread() function outside the else statement as well and got the same result.

Any suggestions?

you're writing the data struct in binary after the human readable version, but you're reading the binary data struct first and then the human readable version. Ignoring the fact that you're writing the information twice in the file (human readable, then binary), if you write/read in the same order it should work.

Here is a 'fixed' version:

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

typedef struct{
  unsigned int sample_offset;
  char receiver_name[20];
  double sample_rate;
  unsigned int channel;
  unsigned int bits;
  char file_type[11];
  unsigned int freq_band;
  double channlel_bandwidth;
  double firmwire_version;
  double header_version;
} sampleInfo;

int main(){
  // Writing into the file                                                                                                                                                                                          
  FILE * fw;
  sampleInfo data = {64, "Gadfly", 51.2, 2, 4, "Spreadsheet", 1,24, 1.0,1.0 };
  sampleInfo read_data;

  fw = fopen("test.bin","wb");
  if (!fw)
    {
      printf("Unable to open the file\n");
      exit(1);
    }
  else
    {
      fprintf(fw,"Sample offset: %u bytes\n\n", data.sample_offset);
      fprintf(fw,"Receiver's name: %s\n\n", data.receiver_name);
      fprintf(fw,"Sample rate: %.2lf Mega-samples per second\n\n", data.sample_rate);
      fprintf(fw,"Number of channels used: %u\n\n", data.channel);
      fprintf(fw,"Number of bits per I and Q sample: %u\n\n", data.bits);
      fprintf(fw,"File type: %s\n\n", data.file_type);
      fprintf(fw,"Frequency band per channel: L%u\n\n",data.freq_band);
      fprintf(fw,"Channel Bandwidth: %.1lfMHz\n\n", data.channlel_bandwidth);
      fprintf(fw,"Firm-wire version: %.1lf\n\n",data.firmwire_version);
      fprintf(fw,"Header version: %.1lf\n\n",data.header_version);
      fwrite(&data,sizeof(sampleInfo),1, fw);
      fclose (fw);
    }

  // Reading from the file                                                                                                                                                                                          
  FILE * fr;
  fr = fopen("test.bin", "rb");
  if (!fr)
    {
      printf("Unable to open the file\n");
      exit(1);
    }
  else
    {
      fscanf(fr,"Sample offset: %u bytes\n\n",&(read_data.sample_offset));
      fscanf(fr,"Receiver's name: %s\n\n", read_data.receiver_name);
      fscanf(fr,"Sample rate: %lf Mega-samples per second\n\n", &(read_data.sample_rate));
      fscanf(fr,"Number of channels used: %u\n\n", &(read_data.channel));
      fscanf(fr,"Number of bits per I and Q sample: %u\n\n",&(read_data.bits));
      fscanf(fr,"File type: %s\n\n", read_data.file_type);
      fscanf(fr,"Frequency band per channel: L%u\n\n", &(read_data.freq_band));
      fscanf(fr,"Channel Bandwidth: %lf MHz\n\n", &(read_data.channlel_bandwidth));
      fscanf(fr,"Firm-wire version: %lf\n\n", &(read_data.firmwire_version));
      fscanf(fr,"Header version: %lf\n\n", &(read_data.header_version));
      fread(&read_data,sizeof(sampleInfo),1, fr);
      fclose(fr);
    }
  return 0;
}

For efficiency, get rid of the fprintf/fscanf lines and just keep the compact binary version. Open the file in notepad and verify it is not human readable. Here is the optimized binary version:

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

typedef struct{
  unsigned int sample_offset;
  char receiver_name[20];
  double sample_rate;
  unsigned int channel;
  unsigned int bits;
  char file_type[11];
  unsigned int freq_band;
  double channlel_bandwidth;
  double firmwire_version;
  double header_version;
} sampleInfo;

int main(){
  // Writing into the file                                                                                                                                                                                          
  FILE * fw;
  sampleInfo data = {64, "Gadfly", 51.2, 2, 4, "Spreadsheet", 1,24, 1.0,1.0 };
  sampleInfo read_data;

  fw = fopen("test.bin","wb");
  if (!fw)
    {
      printf("Unable to open the file\n");
      exit(1);
    }
  else
    {
      fwrite(&data,sizeof(sampleInfo),1, fw);
      fclose (fw);
    }

  // Reading from the file                                                                                                                                                                                          
  FILE * fr;
  fr = fopen("test.bin", "rb");
  if (!fr)
    {
      printf("Unable to open the file\n");
      exit(1);
    }
  else
    {
      fread(&read_data,sizeof(sampleInfo),1, fr);
      printf("Sample offset: %u bytes\n\n", read_data.sample_offset);
      printf("Receiver's name: %s\n\n", read_data.receiver_name);
      printf("Sample rate: %.2lf Mega-samples per second\n\n", read_data.sample_rate);
      printf("Number of channels used: %u\n\n", read_data.channel);
      printf("Number of bits per I and Q sample: %u\n\n", read_data.bits);
      printf("File type: %s\n\n", read_data.file_type);
      printf("Frequency band per channel: L%u\n\n", read_data.freq_band);
      printf("Channel Bandwidth: %.1lfMHz\n\n", read_data.channlel_bandwidth);
      printf("Firm-wire version: %.1lf\n\n", read_data.firmwire_version);
      printf("Header version: %.1lf\n\n", read_data.header_version);
      fclose(fr);
    }
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM