如果我有一个文件,几乎每一行都包含
'\n'
,并且我在 getline()
循环中使用 while
来读取内容,这是不好的做法吗?
我的理解是,对于每个达到的 getline()
字符,'\n'
将被调用多次,因此 realloc()
每次也会被调用。这看起来效率很低?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
perror("Unable to open file: ");
exit(1);
}
char *buffer = NULL;
size_t len = 0;
ssize_t characters;
while ((characters = getline(&buffer, &len, fp)) != -1) {
fputs(buffer, stdout);
}
fclose(fp);
free(buffer);
buffer = NULL;
return 0;
}
按照您的方式循环调用
getline
没有问题。事实上,这正是预期的用例,并在手册页的示例中使用。
仅当到目前为止分配的数组对于当前行来说太短时才会调用 realloc
,因此它的调用次数会很少,您甚至可以通过分配初始数组并在 len
中设置其长度来减少调用次数
变量。
由于
getline
返回读取的字符数,因此您可以使用 fwrite
而不是 fputs
来编写该行。 但请注意,行为略有不同:fwrite
将输出从包含嵌入空字节的文件中读取的行,而fputs
将在第一个空字节处停止。这通常不是问题,因为文本文件通常不包含空字节。
这是修改后的版本:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Unable to open file %s: %s\n",
"file.txt", strerror(errno));
return 1;
}
char *buffer = NULL;
size_t len = 0;
ssize_t characters;
#if 1
// optional code to show how to start with a preallocated buffer
if ((buffer = malloc(256)) != NULL)
len = 256;
#endif
while ((characters = getline(&buffer, &len, fp)) != -1) {
fwrite(buffer, 1, characters, stdout);
}
fclose(fp);
free(buffer);
return 0;
}