C语言 如何在不将其存储在内存中的情况下将文件内容打印到 stdout?



我的程序接收任意长行的文件。 由于我不知道一行上会有多少字符,因此我想将整行打印到 stdout,而无需错误地分配数组来存储它。 这可能吗?

我知道可以一次打印一个块的行 - 但是,执行打印的函数会经常被调用,我希望避免在每次调用中保存输出的错置数组的开销。

首先,你不能打印不存在的东西,这意味着你必须把它存储在某个地方,无论是在堆栈中还是堆中。如果您使用FILE*那么libc将自动为您完成。

现在如果你使用FILE*,你可以使用getc一次获取一个 ASCII 字符,检查该字符是否为换行符并将其推送到 stdout。

如果您使用的是文件描述符,则可以一次read一个字符并执行完全相同的操作。

这两种方法都不需要在堆中显式分配内存。

现在,如果您使用mmap,您可以执行一些strtok族功能,然后将字符串打印到 stdout。

接收具有任意长行的文件...将整行打印到 stdout,无需错误地分配数组来存储它。这可能吗?

一般来说,对于任意长线:不。

文本流是由行组成的有序字符序列,每行由零个或多个字符和一个终止换行符组成。 C11dr §7.21.2 2

直线的长度不限于SIZE_MAX,这是C语言中最长的数组。 一行的长度可以超过计算机的内存容量。 只是没有办法读取任意的长行。 简单的代码可以使用以下内容。 我怀疑它会令人满意,但它确实打印了一个内存不足的文件的全部内容。

// Reads one character at a time.
int ch;
while((ch = fgetc(fp)) != EOF) {
putchar(ch);
}

相反,代码应该在行长度上设置一个合理的上限。 为创建数组或分配。 尽管灵活的长线很有用,但它也容易受到黑客恶意滥用,消耗不受限制的资源。

#define LINE_LENGTH_MAX 100000
char *line = malloc(LINE_LENGTH_MAX + 1);
if (line) {
while (fgets(line, LINE_LENGTH_MAX+1, fp)) {
if (strlen(line) >= LINE_LENGTH_MAX) {
Handle_Possible_Attach();
}
foo(line);  // Use line
}
free(line);
)

最新更新