【问题标题】:Can anyone help? I am trying to read data from a file but its just spitting out garbage任何人都可以帮忙吗?我正在尝试从文件中读取数据,但它只是吐出垃圾
【发布时间】:2022-10-09 11:14:07
【问题描述】:

我正在尝试从文件 hw4.data 中读取并查看它是否有名称。用户通过命令行参数输入名称。一切正常,但我无法让文件在函数之间正确传递。作业要求我在 main 中定义文件并在 SCAN 和 LOAD 之间传递它。

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

struct _data {
    char name[20];
    long number;
};

int SCAN(FILE *(*stream)) { // skim through the file and find how many entries there are
    int size = 0;
    char s_temp[100];
    long l_temp;
    while (1) {
        fscanf(*stream, "%s %ld", s_temp, &l_temp);
        if (feof(*stream)) break;
        size++;
    }
    return size;
}

struct _data* LOAD(FILE *stream, int size) { // loop through the file and load the entries into the main data array
    struct _data* d = malloc(size * sizeof(struct _data));
    int i;
    for (i = 0; i < size; i++) {
        fscanf(stream, "%s %ld", d[i].name, &d[i].number);
    }
    return d;
}

void SEARCH(struct _data *BlackBox, char* name, int size) { // loop through the array and search for the right name

    int i;
    int found = 0;
    for (i = 0; i < size; i++) {
        printf("%s %s\n", BlackBox[i].name, name);
        if (strcmp(BlackBox[i].name, name) == 0) {
            printf("*******************************************\nThe name was found at the %d entry.\n*******************************************\n", i);
            found = 1;
            break;
        }
    }
    if (found == 0) {
        printf("*******************************************\nThe name was NOT found.\n*******************************************\n");
    }
}

void FREE(struct _data* BlackBox, int size) { // free up the dynamic array
    free(BlackBox);
}

int main(int argv, char* argc[]) {
    
    if (argv == 2) {
        printf("The argument supplied is %s\n", argc[1]);

        FILE* file = fopen("./hw4.data", "r");

        int size = SCAN(&file);
        struct _data* data = LOAD(&file, size);

        SEARCH(data, argc[1], size);

        fclose(file);
        return 0;
    } else {
        printf("*******************************************\n* You must include a name to search for.*\n*******************************************\n");
        return 0;
    }
}

这是hw4.data的格式

ron 7774013
jon 7774014
tom 7774015
won 7774016

【问题讨论】:

  • 您的编译器应该向您抱怨:您将 FILE ** 传递给 LOAD 函数,但它只需要一个 FILE * 参数。为什么你还是通过&amp;file?那有什么意义呢?
  • 您必须始终检查 fscanf 等函数的返回值,以确保它们成功。
  • 另外,除非第一个参数是格式字符串,否则不要使用printf,否则使用fputs
  • SCAN 中,删除feof。替换为:if (fscanf(*stream, "%s %ld", s_temp, &amp;l_temp) != 2) break; 请注意,在调用SCAN 之后,您应该这样做:rewind(file);。否则,LOAD 只会看到 [立即] EOF。而且,正如其他人所提到的,只需将file 传递给SCAN/LOAD不是&amp;file。第三,添加对来自fopen(例如)if (file == NULL) { perror("fopen"); exit(1); } 的空返回的检查

标签: c file


【解决方案1】:

几个问题:

  1. SCAN 中,删除feof。替换为:if (fscanf(*stream, "%s %ld", s_temp, &amp;l_temp) != 2) break;
  2. 请注意,在调用SCAN 之后,您应该执行以下操作:rewind(file);。否则,LOAD 只会看到 [立即] EOF。
  3. 正如其他人所提到的,只需将file 传递给SCAN/LOAD不是&amp;file
  4. 添加对来自fopen(例如)if (file == NULL) { perror("fopen"); exit(1); } 的空返回的检查

    风格上:

    1. 如果您有描述函数的注释,请将其放在函数上方的行中。
    2. 尽量将行保持在 80 个字符以内

      这是重构后的代码:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      struct _data {
          char name[20];
          long number;
      };
      
      // skim through the file and find how many entries there are
      int
      SCAN(FILE *stream)
      {
          int size = 0;
          char s_temp[100];
          long l_temp;
      
          while (1) {
              if (fscanf(stream, "%s %ld", s_temp, &l_temp) != 2)
                  break;
              size++;
          }
      
          return size;
      }
      
      // loop through the file and load the entries into the main data array
      struct _data *
      LOAD(FILE *stream, int size)
      {
          struct _data *d = malloc(size * sizeof(struct _data));
          int i;
      
          for (i = 0; i < size; i++) {
              fscanf(stream, "%s %ld", d[i].name, &d[i].number);
          }
      
          return d;
      }
      
      // loop through the array and search for the right name
      void
      SEARCH(struct _data *BlackBox, char *name, int size)
      {
      
          int i;
          int found = 0;
      
          for (i = 0; i < size; i++) {
              printf("%s %s
      ", BlackBox[i].name, name);
              if (strcmp(BlackBox[i].name, name) == 0) {
                  printf("*******************************************
      ");
                  printf("The name was found at the %d entry.
      ", i);
                  printf("*******************************************
      ");
                  found = 1;
                  break;
              }
          }
          if (found == 0)
              printf("*******************************************
      "
                  "The name was NOT found.
      "
                  "*******************************************
      ");
      }
      
      // free up the dynamic array
      void
      FREE(struct _data *BlackBox, int size)
      {
          free(BlackBox);
      }
      
      int
      main(int argv, char *argc[])
      {
      
          if (argv == 2) {
              printf("The argument supplied is %s
      ", argc[1]);
      
              FILE *file = fopen("./hw4.data", "r");
              if (file == NULL) {
                  perror("fopen");
                  exit(1);
              }
      
              int size = SCAN(file);
              rewind(file);
              struct _data *data = LOAD(file, size);
      
              SEARCH(data, argc[1], size);
      
              fclose(file);
          }
          else
              printf("*******************************************
      "
                  "* You must include a name to search for.*
      "
                  "*******************************************
      ");
      
          return 0;
      }
      

      使用realloc,我们可以将SCANLOAD 组合成一个函数:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      struct _data {
          char name[20];
          long number;
      };
      
      // loop through the file and load the entries into the main data array
      struct _data *
      LOAD(FILE *stream, int *sizep)
      {
          struct _data *all = NULL;
          struct _data *d;
          int size = 0;
          int capacity = 0;
      
          while (1) {
              if (size >= capacity) {
                  capacity += 10;
                  all = realloc(all,sizeof(*all) * capacity);
                  if (all == NULL) {
                      perror("realloc");
                      exit(1);
                  }
              }
      
              d = &all[size++];
      
              if (fscanf(stream, "%s %ld", d->name, &d->number) != 2)
                  break;
          }
      
          // trim to size actually used
          all = realloc(all,sizeof(*all) * size);
      
          *sizep = size;
      
          return all;
      }
      
      // loop through the array and search for the right name
      void
      SEARCH(struct _data *BlackBox, char *name, int size)
      {
      
          int i;
          int found = 0;
      
          for (i = 0; i < size; i++) {
              printf("%s %s
      ", BlackBox[i].name, name);
              if (strcmp(BlackBox[i].name, name) == 0) {
                  printf("*******************************************
      ");
                  printf("The name was found at the %d entry.
      ", i);
                  printf("*******************************************
      ");
                  found = 1;
                  break;
              }
          }
          if (found == 0)
              printf("*******************************************
      "
                  "The name was NOT found.
      "
                  "*******************************************
      ");
      }
      
      // free up the dynamic array
      void
      FREE(struct _data *BlackBox, int size)
      {
          free(BlackBox);
      }
      
      int
      main(int argv, char *argc[])
      {
      
          if (argv == 2) {
              printf("The argument supplied is %s
      ", argc[1]);
      
              FILE *file = fopen("./hw4.data", "r");
              if (file == NULL) {
                  perror("fopen");
                  exit(1);
              }
      
              int size;
              struct _data *data = LOAD(file, &size);
      
              SEARCH(data, argc[1], size);
      
              fclose(file);
          }
          else
              printf("*******************************************
      "
                  "* You must include a name to search for.*
      "
                  "*******************************************
      ");
      
          return 0;
      }
      

【讨论】:

    【解决方案2】:

    我必须使用rewind() 来重置文件,以便LOAD() 从文件开头读取并提供良好的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      • 2021-05-12
      相关资源
      最近更新 更多