如何编写子程序以从二进制文件读取并在文本文件中写入?

时间:2019-03-13 19:33:28

标签: c

#include<stdio.h>

typedef struct {
  char floare[40];
  char culoare[30];
  float pret;
  int codf;
}FLOARE;


void creare_fisier(char*nume) {
  FILE*g;
  FLOARE f;
  fopen_s(&g, nume, "wb");
  if (!g)
    printf("Eroare");
  else
  {
    printf("Cod floare:"); scanf_s("%d", &f.codf);
    while (!feof(stdin)) {
        getchar();
        printf("Nume floare:"); gets(f.floare);
        printf("Culoare floare:"); gets(f.culoare);
        printf("Pret:"); scanf_s("%f", &f.pret);
        fwrite(&f, sizeof(FLOARE), 1, g);
        printf("Cod floare:"); scanf_s("%d", &f.codf);
    }
    fclose(g);
  }
}

void afisare_fisier(char*nume) {
  FILE*h;
  FLOARE f;
  fopen_s(&h, "lista.dat", "rb");
  if (!h)
    printf("Eroare");
  else {
    FILE*g;
    fopen_s(&g, nume, "w");
    fread(&f, sizeof(FLOARE), 1, g);
    while (!feof(h)) {
        fprintf(g, "%d %s %s %f", f.codf, f.floare, f.culoare, f.pret);
        fread(&f, sizeof(FLOARE), 1, g);
    }
    fclose(g), fclose(h);
  }
}

void main() {
  char numef[] = "lista.dat";
  creare_fisier(numef);
  char numetxt[] = "raport.txt";
  afisare_fisier(numetxt);
}

创建二进制文件的子程序正在运行,但是将信息列表输入文本文件无效。当我运行代码时,它什么也没有发生,随着我不断打开控制台,文本文件所占用的空间正在增加。我对子程序没有真正的经验,但是我知道列出到文本文件的结构。

这是一项家庭作业。

1 个答案:

答案 0 :(得分:2)

  

当我运行代码时,它什么也没有发生,并且随着我不断打开控制台,文本文件所占用的空间正在增加。

这是因为您使用 feof 并混合了 gets scanf

请注意,您还(尝试)在afisare_fisier

中使用 g 而不是 h 进行阅读

这里有个建议:

我总是使用 fgets stdin 上进行读取,首先是因为它允许指出在 gets 可能溢出接收到的内容时可以读取的最大大小。缓冲区,而不必执行 getchar()或等效操作以希望绕过换行符等。

换行符是读取字符串的一部分,因此在字段 floare culoare 中,可能必须删除它们。

如果 floare culoare 是单词并且不包含空格,则可以替换 fgets (+ sscanf ),使用 fscanf 来使 floare culoare 中没有换行符(当您 fscanf 一个字符串)。

请注意,使用 fgets 的结果来检测EOF(而不是 feof ),我不必将其两次放在源中。

我一直在打开文件时添加了支票

我在afisare_fisier的参数中给出了两个文件的名称,因为没有理由知道输入文件的名称。

因为从标准输入法中获取 EOF 并不容易,所以当无法 sscanf 鳕鱼花时,我也会停下来阅读,在空行上终止(用户刚刚击中<enter>而没有数字)

typedef struct {
  char floare[40];
  char culoare[30];
  float pret;
  int codf;
}FLOARE;


void creare_fisier(char*nume) {
  FILE*g;
  FLOARE f;
  fopen_s(&g, nume, "wb");
  if (!g)
    printf("Eroare");
  else
  {
    char s[32];

    for (;;) {
      printf("Cod floare:");
      if ((fgets(s, sizeof(s), stdin) == NULL) ||
          (sscanf(s, "%d", &f.codf) != 1))
        break;
      printf("Nume floare:"); 
      if (fgets(f.floare, sizeof(f.floare), stdin) == NULL)
        break;
      printf("Culoare floare:"); 
      if (fgets(f.culoare, sizeof(f.culoare), stdin) == NULL)
        break;
      printf("Pret:");
      if ((fgets(s, sizeof(s), stdin) == NULL) ||
          (sscanf(s, "%f", &f.pret) != 1))
        break;
      fwrite(&f, sizeof(f), 1, g);
    }
    fclose(g);
  }
}

void afisare_fisier(char * in, char * out) {
  FILE*h;
  FLOARE f;
  fopen_s(&h, in, "rb");
  if (!h)
    printf("Eroare (in)");
  else {
    FILE*g;
    fopen_s(&g, out, "w");
    if (!g)
      printf("Eroare (out)");
    else {
      while (fread(&f, sizeof(f), 1, h) == 1) { /* read in h, not in g */
        fprintf(g, "%d %s %s %f\n", f.codf, f.floare, f.culoare, f.pret);
      }
      fclose(g);
    }
    fclose(h);
  }
}

int main() {
  char numef[] = "lista.dat";
  creare_fisier(numef);
  char numetxt[] = "raport.txt";
  afisare_fisier(numef, numetxt);
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra f.c
pi@raspberrypi:/tmp $ ./a.out
Cod floare:123
Nume floare:nume1
Culoare floare:culoare1
Pret:12.34
Cod floare:456
Nume floare:nume2
Culoare floare:culoare2
Pret:21.4
Cod floare:
pi@raspberrypi:/tmp $ cat raport.txt
123 nume1
 culoare1
 12.340000
456 nume2
 culoare2
 21.400000

注意:当我要求第三次鳕鱼爆发时,我击中了<enter>