【问题标题】:Reading lines from a file and storing them in an array从文件中读取行并将它们存储在数组中
【发布时间】:2021-06-09 23:16:18
【问题描述】:

我无法逐行读取文件中的文本并将每一行存储到一个数组中。然后我需要打印出我得到的数组。

我不确定我是否为这个数组正确分配了空间。我在read_one_line() 函数中遇到了来自fgets() 的分段错误。

我的代码:

#include <stdio.h>
#include <stdlib.h>
char* read_one_line(FILE* fp, char* line);
char* allocate_mem(FILE* fp, char* line);
void print_lines(char** lines, int num_lines){
    int i;
    for(i = 0 ; i < num_lines; ++i){
        printf("%d. %s", i+1, lines[i]);
    }
}
void free_lines(char** lines, int num_lines){
    int i;

    for(i = 0 ; i < num_lines; ++i){
        free(lines[i]);
    }

    if(lines != NULL && num_lines > 0){
        free(lines);
    }
}
FILE* validate_input(int argc, char* argv[]){

    FILE* fp = NULL;

    if(argc < 2){
        printf("Not enough arguments entered.\nEnding program.\n");
        exit(0);
    }
    else if(argc > 2){
        printf("Too many arguments entered.\nEnding program.\n");
        exit(0);
    }

    fp = fopen(argv[1], "r");

    if(fp == NULL){
        printf("Unable to open file: %s\nEnding program.\n", argv[1]);
        exit(0);
    }
    return fp;
}
void read_lines(FILE* fp, char*** lines, int* num_lines) {
  *num_lines = 0;

  do {
    *num_lines += 1;
    *lines = malloc(*num_lines * sizeof(*lines));
    for(int i = 0; i < *num_lines; ++i) {
      *lines[i] = allocate_mem(fp, *lines[i]);
    }
    read_one_line(fp, *lines[*num_lines]);
  } while(read_one_line(fp, *lines[*num_lines]) != NULL);
}
char* read_one_line(FILE* fp, char* line) {
  fgets(line, sizeof(line), fp);
  return line;
}
char* allocate_mem(FILE* fp, char* line) {
  fseek(fp, 0, SEEK_END);
  int length = ftell(fp);
  fseek(fp, 0, SEEK_SET);
  line = malloc((length + 1) * sizeof(char));
  return line;
}
int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);

    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}

我们将不胜感激!

【问题讨论】:

  • 好像。通过使用调试器确定。它会立即为您提供该信息。
  • @kaylum 我确实使用了调试器,这就是发生分段错误的地方
  • 太棒了。请更新您的问题以这样说。听起来你有点不确定:-)
  • read_lines 中的情况似乎不正常。您应该在分配内存之前计算num_lines。或者使用realloc
  • 旁白:由于ftell() 返回long,推荐long length = ftell(fp); 和错误检查。

标签: c file io fgets


【解决方案1】:

在函数read_one_line中,sizeof(line)不对,line是一个指针,你不会得到容器line的大小,而是指针本身的大小(大概8个字节) ,您需要将容器的实际大小作为函数的参数传递并在fgets 中使用。

【讨论】:

    【解决方案2】:

    嗯。

    lines[*num_lines] 将超过您分配的行数组的末尾。您正在指示 fgets 读取未分配的内存。在你的 read_lines 函数中修复它。

    【讨论】:

      【解决方案3】:

      就是这样(原型)

      FILE* f = fopen();
      int result;
      int n = 0;
      int b = 0;
      int bh = 0;
      
      do
      {
         int a;
         b++;
         fscanf(f,"%*[^\n]%n%*c" , &a);
         n = MAX(n,a);
      } while (feof(f) == false);
      n++;
      char *x = calloc(n*b , sizeof(char));
      rewind(f);
      do
      {
         fscanf(f,"%[^\n]%*c",&x[0][bh]);
         bh++;
      } while (bh < b);
      

      查找并复制粘贴 max 的代码。 #include sys/param.h 在 linux 中,msvc 中也有一个

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 2014-06-25
        • 2021-12-08
        • 2014-08-14
        • 1970-01-01
        相关资源
        最近更新 更多