我的程序接收任意长行的文件。由于我不知道行上会有多少字符,所以我想将整行打印到stdout,而不用malloc-an数组来存储它。这可能吗?
我知道可以一次打印一行这些行 - 但是,执行打印的功能会经常被调用,我希望避免使用malloc-ing数组的开销。在每次通话中保持输出。
答案 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);
)