我正在解析文本文件 - 我可以打开它,读取它并从字符串中删除不必要的部分。
但是,我无法使用此代码:
size_t read_lines(const char *file_name, char **buffer) {
size_t n_lines = 0;
FILE *file = open_file(file_name);
while (1) {
char *ln = _read_line(file);
if (ln == NULL) {
break;
}
n_lines++;
}
fclose(file);
file = open_file(file_name);
buffer = calloc(n_lines, sizeof(char *));
for (int i = 0; i < n_lines; i++) {
buffer[i] = read_line(file);
}
fclose(file);
return n_lines;
}
int main(int argc, const char *argv[]) {
char **lines;
size_t length = read_lines("/Users/honzik/Documents/Xcode/BoioVM/BoioVM/test_file.bic", lines);
for (int i = 0; i < length; i++) {
printf("%s\n", lines[i]);
}
free(lines);
return 0;
}
我知道这可能是糟糕的代码,但只是应该工作
或者可能不是? lines
等于NULL
,但是如何通过函数更新指针?
PS:不要担心他们工作的所有这些功能(open_file
,read_line
,_read_line
,...): < / p>
答案 0 :(得分:1)
假设read_line()
按预期工作,你想要实现的只有三星指针,恕我直言,这是一个可以使用它的情况,因为它不是真正的三星指针,它是一个双星指针,其地址被传递给一个函数。
char
函数中的双read_lines()
指针是函数的局部变量,因此当函数返回时,不会保存calloc()
中返回的地址,而是你应该传递指针的地址,并通过解引用指针并将它指定给calloc()
中定义的真正的两颗星指针来存储返回值main()
,有点像这样
size_t read_lines(const char *file_name, char ***buffer)
{
size_t n_lines = 0;
FILE *file = open_file(file_name);
// FIXME: check if `file != NULL' before reading
while (1) {
char *ln = _read_line(file);
if (ln == NULL)
break;
n_lines++;
}
fclose(file);
file = open_file(file_name);
// FIXME: check if `file != NULL' before reading
*buffer = malloc(n_lines * sizeof(**buffer));
// FIXME: check that `malloc' did not return `NULL'
for (int i = 0; i < n_lines; i++)
(*buffer)[i] = read_line(file);
fclose(file);
return n_lines;
}
请注意:
我将calloc()
替换为malloc()
,因为该行应null
在read_line()
内终止。在这种情况下使用calloc()
可以隐藏一些非常难以调试的错误。如果您改为使用malloc()
,则可以使用valgrind等工具轻松揭示潜在错误。
我添加了smoe注释,让您看到您的代码非常不安全。
在main()
上你会这样做
#define PLEASE_AVOID_SUCH_LONG_LINES "/Users/honzik/Documents/Xcode/BoioVM/BoioVM/test_file.bic"
size_t length = read_lines(PLEASE_AVOID_SUCH_LONG_LINES, &lines);
/* long lines make the code hard to read even on modern editors */