如何将文件内容打印到stdout而不将它们存储在内存中?

时间:2017-07-19 22:36:25

标签: c io stdout

我的程序接收任意长行的文件。由于我不知道行上会有多少字符,所以我想将整行打印到stdout,而不用malloc-an数组来存储它。这可能吗?

我知道可以一次打印一行这些行 - 但是,执行打印的功能会经常被调用,我希望避免使用malloc-ing数组的开销。在每次通话中保持输出。

2 个答案:

答案 0 :(得分:1)

首先,您无法打印不存在的内容,这意味着您必须将其存储在堆栈或堆中的某个位置。如果您使用FILE*,则libc会自动为您执行此操作。

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

如果你正在使用文件描述符,你可以read一个角色一次并做同样的事情。

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

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

答案 1 :(得分:0)

  

接收具有任意长行的文件...将整行打印到stdout,而不用malloc-an数组来存储它。这可能吗?

一般来说,对于任意长行:否。

  

文本流是由行组成的有序字符序列,每行由零个或多个字符加上终止的换行符组成。 C11dr§7.21.22

行的长度不限于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);
)