我创建了一个函数,用于查找文件中的行数 (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/