Чтение данных из двоичного файла на c

Я новичок в 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;
}

И вот что я получаю в результате:

Выход

Я не могу понять, почему программа показывает только операторы печати в качестве вывода и не считывает все данные из файла должным образом. Я пробовал использовать функцию fread () вне оператора else и получил тот же результат.

Какие-либо предложения?

Блокнот - это редактор текст. Вы видите все данные, которые вы написали с помощью fprintf, а затем следуете за двоичными данными, которые блокнот не может вам правильно отобразить.

Paul Ogilvie 31.10.2018 12:26

@PaulOgilvie Итак, как я могу убедиться, что все данные были прочитаны программой?

abc18 31.10.2018 12:42

@ abc18 - Вы должны использовать fwrite с fread. ИЛИ вы можете использовать fprintf и fscanf. Нет смысла использовать все четыре вместе.

Rishikesh Raje 31.10.2018 12:49

@RishikeshRaje Я знаю, что ты имеешь в виду. Но я хотел распечатать заявления, а также прочитать их из файла.

abc18 31.10.2018 13:07

Я бы сказал, возможно, ошибка форматирования в последней строке чтения файла ... fscanf(fr,"Header version: %lf\n", &(read_data.header_version)); вместо fscanf(fr,"Header version: %lf\n\n\n", &(read_data.header_version));. Но не уверен. Не тестировал

PhoenixBlue 31.10.2018 14:04

@PhoenixBlue Попробовал и получил тот же результат. Я даже пробовал использовать разные спецификаторы формата (% e,% E,% g,% G), совместимые с типом double. Продолжайте получать то же самое.

abc18 31.10.2018 14:24
2
6
1 983
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вы пишете структуру данных в двоичном формате после версии, доступной для чтения человеком, но сначала вы читаете структуру двоичных данных, а затем версию, удобную для чтения. Игнорируя тот факт, что вы дважды записываете информацию в файл (читаемый человеком, затем двоичный), если вы пишете / читаете в одном и том же порядке, это должно работать.

Вот «фиксированная» версия:

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

Спасибо за исправление кода. Я наконец нашел свою ошибку.

abc18 31.10.2018 15:13

Всегда пожалуйста. Пожалуйста, проголосуйте за и / или примите ответ, если он был полезен.

Tezirg 31.10.2018 15:16

По какой-то причине система не поддерживает голосование, поэтому я поставил галочку, чтобы принять ответ как полезный.

abc18 31.10.2018 15:31

Другие вопросы по теме