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

时间:2018-09-08 08:57:13

标签: c input null scanf

我正在用C编写代码,我需要阅读输入中到达的所有内容,但我不知道我将收到多少个字符。我写了

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

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

2 个答案:

答案 0 :(得分:2)

相反,您可以考虑在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 <stdio.h>

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处理,表示格式为最大的字符串。 width *,其中width和string被读取为连续参数。

Live Demo on ideone

答案 1 :(得分:0)

您的

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

是输入错误:!=的左右操作数类型不匹配。了解有关type systems的信息。

阅读documentation of 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更好(可读性更好,并且可能更快)。阅读documentation of fgetc,并遵循Sheff's answer的建议。

下次:

  • 请确保阅读所使用的每个功能的文档。切勿使用尚未阅读和理解其文档的功能。

  • 要求编译器给出所有警告和调试信息,因此使用GCC编译with gcc -Wall -Wextra -g。相信您的编译器,并改善您的代码以完全不发出警告

  • 阅读How To Debug Small Programs

  • 阅读documentation of gdb(也许还有valgrind)。

  • 研究一些与您类似的小型free software的源代码(也许在github上作为灵感)。

PS。给变量read命名是不好的味道。对于大多数人来说,它与POSIX read函数有冲突。