c - 如何在C中为文件的行分配内存?

标签 c

我创建了一个函数,用于查找文件中的行数 (find_numlines()) 和一个将文件行读入 char*** 行的函数 (read_lines())。我的 main 中的其余函数已提供,因此问题不在这些函数中。

read_lines.c(已更新):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "read_lines.h"


int findnum_lines(FILE* fp){

  int num_lines = 0;
  int line;

  line = getc(fp);
  if (line != EOF) {
    num_lines++;
    do {
      if (line == '\n') {
        num_lines = num_lines + 1;
      }
      line = getc(fp);
    }
    while (line != EOF);
  }
  rewind(fp);
  return num_lines;
}


void read_lines(FILE* fp, char*** lines, int* num_lines){

  int i;

  (*lines) = malloc(*num_lines * sizeof(char*));

  for (i=0; i < *num_lines; i++)
  {
    (*lines)[i] = malloc(1000);
    (*lines)[i][0] = '\0';
    fgets((*lines)[i], 1000, fp);
  }
}

main.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "read_lines.h"


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){
        perror("fopen");
        printf("Unable to open file: %s\nEnding program.\n", argv[1]);
        //fprintf(stderr, "Unable to open file %s: %s\n", argv[1], strerror(errno));
        exit(0);
    }

    return fp;

}


int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);

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

    return 0;
}

read_lines.h:

#ifndef READ_LINES
    #define READ_LINES
    #include <stdio.h>
    void read_lines(FILE* fp, char*** lines, int* num_lines);
    int findnum_lines(FILE* fp);
#endif

每当我输入文件时,find_numlines()都会返回正确的行数,但read_lines()会出现问题,因为lines仍然是NULL

示例文件是normal.txt:

Hello Class
This is what I would call a normal file
It isn't very special
But it still is important

输出应该是:

1. Hello Class
2. This is what I would call a normal file
3. It isn't very special
4. But it still is important

最佳答案

在下面的代码中,我添加了rewind命令(由xing提到)以及行和“行表”的内存分配。对行数计数和错误处理的代码进行了进一步改进。

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

int findnum_lines(FILE* fp){

  int num_lines = 0;
  int c;

  c = getc(fp);
  if (c != EOF) {
    num_lines++;
    do {
        if (c == '\n') {
            num_lines = num_lines + 1;
        }
        c = getc(fp);
    }
    while (c != EOF);
  }
  rewind(fp);
  return num_lines;
}

void read_lines(FILE* fp, char*** lines, int* num_lines){

  int i;

  // allocate memory for pointers to start of lines
  (*lines) = malloc(*num_lines * sizeof(char*));

  for (i=0; i < *num_lines; i++)
  {
    (*lines)[i] = malloc(1000);
    (*lines)[i][0] = '\0'; // terminate for the case that last line does not contain characters
    fgets((*lines)[i], 1000, fp); // read up to 999 characters and terminate string
  }

}

void print_lines(char** lines, int num_lines){
    int i;
    for(i = 0 ; i < num_lines; ++i){
        printf("%d. %s", i+1, lines[i]);
    }
    printf("\n");
}

void free_lines(char** lines, int num_lines){
    int i;
    for (i = 0 ; i < num_lines; ++i) {
        if (lines[i]!=NULL) {
            free(lines[i]);
        }
    }
    if (lines != NULL){
        free(lines);
    }
}

FILE* validate_input(int argc, char* argv[]){

    FILE* fp = NULL;

    if (argc < 2){
        printf("Not enough arguments entered.\n");
    }
    else if (argc > 2){
        printf("Too many arguments entered.\n");
    }
    else {
        fp = fopen(argv[1], "r");
        if (fp == NULL){
            printf("Unable to open file: %s\n", argv[1]);
        }
    }
    return fp;
}


int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);
    if (fp != NULL)
    {
        num_lines = findnum_lines(fp);
        read_lines(fp, &lines, &num_lines);
        print_lines(lines, num_lines);
        free_lines(lines, num_lines);
        fclose(fp);
    }
    return 0;
}

关于c - 如何在C中为文件的行分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56469071/

相关文章:

c - 如果我们只有一个 MQ,则同步 IBM MQ : need or not,

c - 如何使用 memcpy 设置字节数?

c - 强行打印垃圾字符

c++ - C - printf 和 scanf - 如何终止输入?

c - 如何在 C 中从 stdin 进行非阻塞输入

c - 双向链表的双重自由错误

c - MPI 中的不同进程之间发送和接收

javascript - Emscripten 未优化

C - 如何显示数组中低于数组中数字平均值的数字

使用 strdup 后无法释放内存