简体   繁体   English

从 C 中的二进制文件读取数据

[英]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.我是 C 新手,试图将一些数据写入二进制文件并从中读取。 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.我也尝试在 else 语句之外使用 fread() 函数并得到相同的结果。

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.为了提高效率,去掉 fprintf/fscanf 行,只保留紧凑的二进制版本。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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