为什么将scanf()的结果与NULL进行比较会产生编译器警告?

我用C语言写作,我需要阅读输入中的所有内容,但我不知道会收到多少个字符。 我写

while (scanf("%c", &read) != NULL) 

但是编译器告诉我: [Warning] comparison between pointer and integer ,那么我应该写什么呢?

相反, scanf("%c", &read)可以考虑read = getc(stdin)

请注意, getc() / fgetc()返回int

这允许在范围[0,255]中存储任何字符作为数字,以及在发生故障时返回EOF (通常为-1)。

所以,使用getc()它看起来像:

 int read; while ((read = getc(stdin)) != EOF) 

注意:

您可以将read赋值给char类型的变量 – 它将被隐式转换。 如果getc()成功,则此隐式转换中不应存在任何数据丢失。


一个小样本在工作中显示:

 #include  int main(void) { enum { N = 10 }; char buffer[N]; /* read characters and print if buffer ful */ int read, n = 0; while ((read = getc(stdin)) != EOF) { if (n == N) { printf("%.*s", N, buffer); n = 0; } buffer[n++] = read; } /* print rest if buffer not empty */ if (n > 0) printf("%.*s", n, buffer); /* done */ return 0; } 

注意:

读取的字符存储在buffer没有终止'\0' 。 这在printf()分别由格式化程序%.*s表示字符串为max。 width *其中width和string作为连续参数读取。

在ideone上现场演示

您的

 scanf("%c", &read) != NULL 

是一个打字错误:左边和右边操作数的类型!=不匹配。 阅读类型系统 。

阅读scanf的文档 。 它说scanf返回一些int值。

NULL是一个指针值(它是(void*)0 )。

如何将指针与int进行有意义的比较? 在我的Debian / x86-64上,它们甚至没有相同的大小(由sizeof返回):一个指针需要8个字节,但一个int占用4个字节。

所以编译器正确地警告你。

您可能希望编写类似while (scanf("%c", &read) >0)或甚至while (scanf("%c", &read) == 1)因为成功扫描"%c" scanf函数记录为1。

当然,在这种特殊情况下,使用fgetc更好(更具可读性,可能稍快)。 阅读fgetc文档并遵循Sheff的回答给出的建议。

下次:

  • 请务必阅读您正在使用的每个function的文档 。 切勿使用您未阅读和理解其文档的function。

  • 请求编译器提供所有警告和调试信息,以便GCC 使用 gcc -Wall -Wextra -g编译。 相信你的编译器,并改进你的代码,根本没有警告

  • 阅读如何调试小程序

  • 阅读gdb (也许是valgrind )的文档 。

  • 研究,获取灵感,一些类似于你的小型免费软件的源代码(也许在github上 )。

PS。 命名变量read的味道很差。 对于大多数人来说,它与POSIX readfunction冲突。