fgets()
读取换行符并将换行符保留在字符串中,并puts()
始终在要打印的字符串中添加换行符。因此,当在代码中使用时,您会得到双倍行距的输出。
使用fputs(str, stdout)
代替puts()
; 它不添加换行符。
过时的函数gets()
——从 2011 版本的 C 标准中删除——读取到换行符但删除了它。gets()
和puts()
对一起工作得很好, 和也是fgets()
如此fputs()
。但是,您当然不应该使用gets()
; 这是一场等待发生的灾难。(1988 年第一个互联网蠕虫曾经gets()
迁移——谷歌搜索“莫里斯互联网蠕虫”)。
在评论中,调查官问道:
为什么需要将行读入特定大小的 char 数组?
因为您需要确保不会超出可用空间。C 不会为字符串自动分配空间。从某些角度来看,这是它的弱点之一。它也是一种优势,但它经常使语言新手感到困惑。如果您希望输入代码为一行分配足够的空间,请使用 POSIX 函数getline()
。
那么在我点击 a 之前读取和输出是否更好,'\0'
因为我并不总是知道给定行上的字符数量?
不。一般来说,你不会打'\0'
;大多数文本文件不包含任何这些。如果您不想为一行分配足够的空间,请使用:
int c;
while ((c = getchar()) != EOF)
putchar(c);
它在用户代码中一次读取一个字符,但底层标准 I/O 包会缓冲输入,因此成本不会太高——以这种方式实现程序是完全可行的。如果您需要处理线条,请为线条分配足够的空间(我char buffer[4096];
经常使用)或使用getline()
.
查理伯恩斯在评论中问道:
为什么我们不经常看到建议使用 getline()?
我认为它并没有经常被提及,因为getline()
它相对较新,而且不一定在任何地方都可用。它被添加到 POSIX 2008;它在 Linux 和 BSD 上可用。我不确定其他主流 Unix 变体(AIX、HP-UX、Solaris)。为自己编写并不难(我已经完成了),但是如果您需要编写可移植的代码(特别是如果“可移植”包括“微软”),那就很麻烦了。它的优点之一是它告诉你它实际读取的行有多长。
使用示例getline()
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char *line = 0;
size_t length = 0;
char const name[] = "/myFile/path/test.txt";
FILE *file = fopen(name, "r");
if (file == NULL)
{
fprintf(stderr, "%s: failed to open file %s\n", argv[0], name);
return -1;
}
while (getline(&line, &length, file) > 0)
fputs(str, stdout);
free(line);
fclose(file);
return 0;
}