c - 从C语言的二进制文件中读取数据

标签 c file binary

我是 C 新手,尝试将一些数据写入二进制文件并从中读取。结构体成员有字符数组和整数。当我运行代码并通过记事本打开二进制文件时,我只能看到程序正在读取字符串。这是我的代码:

#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;
}

这就是我得到的输出:

Output

我不明白为什么程序只显示打印语句作为输出,而没有正确读取文件中的所有数据。我也尝试在 else 语句之外使用 fread() 函数,并得到了相同的结果。

有什么建议吗?

最佳答案

您在人类可读版本之后以二进制形式编写数据结构,但您首先读取二进制数据结构,然后再读取人类可读版本。 忽略您在文件中写入两次信息的事实(人类可读,然后是二进制),如果您以相同的顺序写入/读取,它应该可以工作。

这是一个“固定”版本:

#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;
}

为了提高效率,请删除 fprintf/fscanf 行并仅保留紧凑的二进制版本。在记事本中打开该文件并验证它不是人类可读的。 这是优化的二进制版本:

#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;
}

关于c - 从C语言的二进制文件中读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53082143/

相关文章:

binary - 计算 Redshift 列中每个位位置中 '1' 值的数量

BASH - 将十六进制字符串写入二进制文件

c - 如何在不在回调函数中使用 pcap_breakloop() 的情况下从 pcap_loop() 或 pcap_dispatch() 返回

将链表复制到另一个链表 - 迭代 - C - 理解返回的列表

c - 从 execv 启动终端 (sh) 返回错误 :/bin/sh:/bin/sh: cannot execute binary file

c# - 使用本地数据库在 WPF 中存储/处理文件附件的最佳方式是什么?

c - 数组的数组,具有不同的大小

php - 使用 PHP 列出 .txt 文件中的项目

java - JAVA中获取文件路径

c - 为什么C中的unsigned char数据类型是00000000 - 00000001 = 11111111?