如何停止在C中读取文件

如何停止在C中读取文件,c,stdio,C,Stdio,我只是试图读取文件中的每个字符并打印出来,但是当文件读取完毕时,我得到了一堆?读完之后。我怎么修理它 #include <stdio.h> int main(void){ FILE *fr; /* declare the file pointer */ fr = fopen ("some.txt", "r"); /* open the file for reading */ /* elapsed.dta is the nam

我只是试图读取文件中的每个字符并打印出来,但是当文件读取完毕时,我得到了一堆?读完之后。我怎么修理它

#include <stdio.h>

int main(void){
    FILE *fr;            /* declare the file pointer */

    fr = fopen ("some.txt", "r");  /* open the file for reading */
        /* elapsed.dta is the name of the file */
        /* "rt" means open the file for reading text */
    char c;
    while((c = getc(fr)) != NULL)
    {
        printf("%c", c);
    }
    fclose(fr);  /* close the file prior to exiting the routine */
    /*of main*/ 


    return 0;
}
#包括
内部主(空){
FILE*fr;/*声明文件指针*/
fr=fopen(“some.txt”,“r”);/*打开文件进行读取*/
/*appeased.dta是文件名*/
/*“rt”表示打开文件以读取文本*/
字符c;
while((c=getc(fr))!=NULL)
{
printf(“%c”,c);
}
fclose(fr);/*退出例程前关闭文件*/
/*主要的*/
返回0;
}

fgetc()
在文件末尾返回
EOF
,而不是
NULL
将“NULL”替换为“EOF”。

如果失败,
fgetc()
返回EOF

int c;
while ((c = getc(fr)) != EOF) 
{ 
    printf("%c", c); 
}
改变这个

char c;
while((c = getc(fr)) != NULL)
{
    printf("%c", c);
}


换句话说:您需要与
EOF
进行比较,而不是
NULL
。您还需要使用
int
变量从
fgetc
接收返回值。如果您使用
char
,与
EOF
的比较可能会失败,您将回到开始的位置。

其他人已经解决了您遇到的问题,但没有使用
printf(“%c”,c)putchar(c)可能更有效。当您要求
printf
只打印一个字符时,会涉及相当大的开销。

getc返回一个int

字符c更改为int c

同样getc返回EOF
将针对NULL的测试更改为针对EOF

的测试,不管其名称如何,
getc
返回一个
int
,而不是
char
,以便它可以表示所有可能的char值,此外,
EOF
(文件结尾)。如果
getc
返回一个
char
,那么如果不使用文件中可能存在的某个值,就无法指示文件的结尾

因此,要修复代码,必须首先更改声明
charc
intc以便在返回时可以保存EOF标记。然后,还必须更改while循环条件以检查
EOF
,而不是
NULL


您还可以调用
feof(fr)
,在读取字符的同时单独测试文件的结尾。如果您这样做了,您可以将
c
作为
char
保留,但是您必须在读取字符后但在打印之前调用
feof()
,并使用
中断来退出循环。

您是否尝试过在启用所有警告的情况下编译?我觉得你的while循环条件是个问题,但我不确定。如果这正是我所想的,那么如果在启用所有警告的情况下编译,就会出现警告。关于该文件,您需要了解的一切都在这里:您应该更加小心
getc()
的返回类型,并且还要意识到
NULL
是一个指针。c也需要声明为int。@Emerick Rogul:你想在原始问题下得到这个注释吗?许多其他函数需要type
int
,即使它们通常只在
char
范围内运行
putchar
isdigit
strchr
等。正确,但使用
fgetc
而不是
fgets
fscanf
也是如此。此外,超弦正在尝试学习C。在这一点上,无穷小的开销并不重要,学习如何使用printf通常比putchar更有用。由于这不是问题的答案,您应该留下一条评论。将
getc
putchar
一起使用更有意义,因为一个用于从
stdin
读取一个字符,另一个用于将一个字符输出到
stdout
。即使效率是一个问题(这不是问题),这个程序肯定是I/O绑定的,而不是CPU绑定的,所以
printf
putchar
之间的区别是可以忽略的。是的,你说得很对。然而,我仍然认为在这种情况下,
putchar
是一个更好的函数选择。@jamesdlin:谢谢你的警告。Nit:C中,普通的
char
可以是有符号的,也可以是无符号的。当
char
未签名时,上述语句是正确的,但如果
char
已签名,则它可能能够表示
EOF
。通常,
EOF
是一个很小的负常量(-1),很容易用
有符号字符
表示。唯一可靠且可移植地测试EOF的方法是使用
feof
@Alok:我看不出它与
char
本身是否被签名有什么关系
getc
将字符作为转换为
int
无符号字符返回。但是,如果
sizeof(int)=1
,则确实会发生
EOF
冲突。@jamesdlin:如果一个字符是无符号的,它永远不能等于
-1
,但是如果它是有符号的,那么它可以等于
-1
,因此等于
EOF
char c;
int charAsInt;
while((charAsInt = getc(fr)) != EOF)
{
     c = (char) charAsInt;
     printf("%c", c);
}