在这看,这两个程序在我看来应该是等同的。但显然它们不是,因为第一个程序可行,第二个不可行。有人可以向我解释,为什么fgets()不能完成这项工作?
// FIRST PROGRAM : WORKS FINE
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stream;
char fileName[67];
scanf("%s", fileName);
printf("%s", fileName);
stream = fopen(fileName, "r");
char ch;
if(stream){
ch = fgetc(stream);
while(!feof(stream)){
putchar(ch);
ch = fgetc(stream);
}
fclose(stream);
}
}
// SECOND PROGRAM: DOES NOT WORK
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stream;
char fileName[67];
fgets(fileName, 67, stdin);
printf("%s", fileName);
stream = fopen(fileName, "r");
char ch;
if(stream){
ch = fgetc(stream);
while(!feof(stream)){
putchar(ch);
ch = fgetc(stream);
}
fclose(stream);
}
}
我在控制台中输入“test.txt”两次,然后按Enter键。当然test.txt存在于正确的目录
中答案 0 :(得分:4)
原因是fgets()
保留了输入的newline
。您可以通过将打印语句更改为
printf("[%s]", filename);
当]
出现在下一行时。您可以删除这样的尾随newline
#include <string.h>
...
filename [ strcspn(filename, "\r\n") ] = 0;
答案 1 :(得分:1)
您遇到的主要问题是由Weather Vane正确解决的,但我想指出您的代码的另一个问题:用于读取和写入文件内容的循环不正确。使用feof(stream)
测试文件末尾会导致大多数时间的行为不正确。在您的情况下,来自stream
的读取错误将导致程序无休止地循环,将0xFF
个字节写入stdout
。
实现此循环有一种更简单和惯用的方法:
if (stream) {
int ch;
while ((ch = fgetc(stream)) != EOF) {
putchar(ch);
}
fclose(stream);
}
正如您所看到的,当输入失败时,它会在正确的时间更简单且正确地测试EOF
。它将fgetc()
的返回值存储到int
变量中,该变量能够保存fgetc()
的所有可能返回值。使用int
是必要的,因为将char
值与EOF
进行比较,如果char
类型未签名,或者如果char
已签名则可能会出现误报,则始终会失败并且值为'\377'
。