C 读取文本文件时出错;行读两遍,每隔一行有额外的换行符

C 读取文本文件时出错;行读两遍,每隔一行有额外的换行符,c,file-io,C,File Io,我正在读一个文本文件(写在UNIX或Linux机器上),每行应该有一个条目。当我用我的程序读取它并将文件内容输出到控制台时,每一个条目都有一个额外的换行符,每一行重复两次。这是密码 FILE* fullList; char sline[21]; fullList = fopen("fullList", "r"); if(fullList == NULL) exit(EXIT_FAILURE); while(fgets(sline, sizeof(sline), fullList) !=

我正在读一个文本文件(写在UNIX或Linux机器上),每行应该有一个条目。当我用我的程序读取它并将文件内容输出到控制台时,每一个条目都有一个额外的换行符,每一行重复两次。这是密码

FILE* fullList;
char sline[21];
fullList = fopen("fullList", "r");
if(fullList == NULL)
    exit(EXIT_FAILURE);
while(fgets(sline, sizeof(sline), fullList) != NULL)
{
    puts(sline);
    printf(sline);
}
fclose(fullList);
因此,如果输入文件包含

apple
banana
orange
zucchini
cucumber
eggplant
程序会将其显示为

apple

apple
banana

banana
orange

orange
zucchini

zucchini
cucumber

cucumber
eggplant
eggplant

我不知道这是怎么回事。在再次使用之前,我必须了解一下sline的清晰度吗?

你认为这有什么用

puts(sline);
printf(sline);
第一个打印行(后面是换行!)。第二个打印行,但以特殊方式格式化以%开头的任何内容。因此,
put()
为您提供了一个额外的换行符,但
printf()
更糟糕——请查阅文档,并思考如果文件包含“%s”或“%d”,会发生什么情况

所以您只想使用一条输出语句,而不想使用两条换行符。您可以在打印前删除每行的换行符,但更好的方法是使用不添加换行符的
fputs(sline,stdout)


另一方面,有一点建议:使用C来处理文本文件对您(作为C的新手)来说将是非常痛苦的。我建议您使用其他语言,如Python、Ruby、awk、sed或其他任何基于您的需要和经验的语言。

您认为这有什么用

puts(sline);
printf(sline);
第一个打印行(后面是换行!)。第二个打印行,但以特殊方式格式化以%开头的任何内容。因此,
put()
为您提供了一个额外的换行符,但
printf()
更糟糕——请查阅文档,并思考如果文件包含“%s”或“%d”,会发生什么情况

所以您只想使用一条输出语句,而不想使用两条换行符。您可以在打印前删除每行的换行符,但更好的方法是使用不添加换行符的
fputs(sline,stdout)


另一方面,有一点建议:使用C来处理文本文件对您(作为C的新手)来说将是非常痛苦的。我建议使用其他语言,如Python、Ruby、awk、sed,或根据您的需要和经验使用其他任何语言。

这是因为每行打印两次—一次通过puts,一次通过printf

fgets
捕获换行符
\n
,而
放置
附加一个自己的
'\n'
,因此在第一次打印输出后还有一个额外的换行符

文件中的最后一行(
“egggplant”
)缺少尾随的
'\n'
,因此在两个egggplant打印输出之间没有额外的空行

要解决此问题,请首先停止调用其中一个打印函数。接下来,确保您阅读的行末尾没有
\n
。你可以自己把它脱掉,也可以用

while (fscanf(fulllist, "%20s", sline) == 1) {
    ...
}
不建议在形式参数处使用字符串调用
printf
,因为在形式参数处使用意外的格式符号可能会导致未定义的行为。如果您决定使用
printf
,请按如下方式使用:

printf("%s\n", sline);

这是因为每行打印两次—一次通过puts,一次通过printf

fgets
捕获换行符
\n
,而
放置
附加一个自己的
'\n'
,因此在第一次打印输出后还有一个额外的换行符

文件中的最后一行(
“egggplant”
)缺少尾随的
'\n'
,因此在两个egggplant打印输出之间没有额外的空行

要解决此问题,请首先停止调用其中一个打印函数。接下来,确保您阅读的行末尾没有
\n
。你可以自己把它脱掉,也可以用

while (fscanf(fulllist, "%20s", sline) == 1) {
    ...
}
不建议在形式参数处使用字符串调用
printf
,因为在形式参数处使用意外的格式符号可能会导致未定义的行为。如果您决定使用
printf
,请按如下方式使用:

printf("%s\n", sline);

奇怪的是,我去掉了
fputs()
,它修复了一切,包括额外的换行。@Celeritas在最后一行(即茄子)之后应该没有换行,对吗?奇怪的是,我去掉了
fputs()
,它修复了一切,包括额外的换行符。@Celeritas在最后一行(即茄子)之后不应该有换行符,对吗?请注意,使用
printf(sline)
是危险的,如果
sline
包含任何
%
符号,当
printf()
试图访问未传递给它的参数时,您很容易崩溃。使用:
printf(“%s”,sline)
;这是安全的。请注意,使用
printf(sline)
是危险的。如果
sline
包含任何
%
符号,则当
printf()
尝试访问未传递给它的参数时,您很容易崩溃。使用:
printf(“%s”,sline)
;那很安全。