我正在尝试创建一个函数read_lines,该函数需要一个文件* fp,一个指向char **行的指针以及一个指向int num_lines的指针。该函数应将每一行文本插入到行中,并将num_lines增加到文件包含的行数。
它可能真的很简单,但是我已经尝试插入文本几个小时了。
这是main.c的外观。除了read_lines之外的所有东西都已经定义并且可以正常工作。
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;
}
这是我尝试添加行的尝试之一,但我无法弄清楚。
read_lines.c
void read_lines(FILE *fp, char ***lines, int *num_lines) {
int i;
int N = 0;
char s[200];
for (i=0; i<3; i++)
{
while(fgets(s, 200, fp)!=NULL){N++;}
char strings[50][200];
rewind(fp);
fgets(s, 200, fp);
strcpy(lines[i],s);
}
}
感谢您为解决此问题提供的帮助。
答案 0 :(得分:2)
一种解决方案(不包含标题和错误检查以提高可读性)
void read_lines(FILE *stream, char ***lines_ptr, size_t *num_lines_ptr) {
char **lines = NULL;
size_t num_lines = 0;
char *line = NULL;
size_t len = 0;
ssize_t nread;
while ((nread = getline(&line, &len, stream)) != -1) {
lines = lines == NULL
? malloc(sizeof(char*))
: realloc(lines, (num_lines+1)*sizeof(char*));
lines[num_lines] = malloc(nread+1);
memcpy(lines[num_lines], line);
++num_lines;
}
free(line);
*lines_ptr = lines;
*num_lines_ptr = num_lines;
}
完整解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// lines_ptr: Output. Initial value ignored. To be freed by caller on success.
// num_lines_ptr: Output. Initial value ignored.
// Returns: 0 on error (errno set). 1 on success.
int read_lines(FILE *stream, char ***lines_ptr, size_t *num_lines_ptr) {
char ***lines = NULL;
size_t num_lines = 0;
char *line = NULL;
size_t len = 0;
ssize_t nread;
while ((nread = getline(&line, &len, stream)) != -1) {
char **new_lines = lines == NULL
? malloc(sizeof(char*))
: realloc(lines, (num_lines+1)*sizeof(char*));
if (new_lines == NULL)
goto error;
lines = new_lines;
lines[num_lines] = malloc(nread+1);
if (lines[num_lines] == NULL)
goto error;
memcpy(lines[num_lines], line);
++num_lines;
}
if (ferror(stream))
goto error;
free(line);
*lines_ptr = lines;
*num_lines_ptr = num_lines;
return 1;
error:
for (size_t i=num_lines; i--; )
free(lines[i]);
free(lines);
free(line);
*lines_ptr = NULL;
*num_lines_ptr = 0;
return 0;
}
(您可以通过使用..._ptr
变量来保存三行,而不用在末尾设置它们,但这真的值可读性吗?)
答案 1 :(得分:0)
我发现fget难以使用,麻烦也超过了它的价值。这是一种基于fgetc和基于malloc的方法:
void read_lines(FILE *fp, char ***lines, int *num_lines) {
int c;
size_t line = 0;
size_t pos = 0;
size_t len = 64;
*lines = malloc(1 * sizeof(char*));
(*lines)[0] = malloc(len);
while ((c = fgetc(fp)) != EOF) {
if (c == '\n') {
(*lines)[line][pos] = '\0';
line++;
pos = 0;
len = 64;
*lines = realloc(*lines, (line+1) * sizeof(char*));
} else {
(*lines)[line][pos] = c;
}
pos++;
if (pos >= len) {
len *= 2;
(*lines)[line] = realloc((*lines)[line], len);
}
}
*num_lines = line+1;
}
我还没有检查这个问题,所以如果我有任何错误,请纠正我。另外,在真实代码中,您将在这里进行很多错误检查,而我已经省略了。
答案 2 :(得分:-1)
assuming you have allocated enough memory to lines, following should work
if not you have to malloc/calloc() for lines[i] before doing strcpy() in every
iteration of the loop.
void read_lines(FILE *fp, char ***lines, int *num_lines) {
int N = 0;
char s[200];
while(fgets(s, 200, fp)!=NULL){
N++;
strcpy((*lines)[N],s);
}
*num_lines = N; // update pointer with value of N which is number of lines in file
}