Why does comparing the result of scanf() with NULL generate a compiler warning?

佐手、 提交于 2019-12-25 18:42:33

问题


I'm writing in C and I need to read everything that arrives in input but I don't know how many characters I will receive. I wrote

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

but the compiler tells me: [Warning] comparison between pointer and integer, so what should I write instead?


回答1:


Instead, of scanf("%c", &read) you may consider read = getc(stdin).

Please, be aware that getc()/fgetc() return int.

This allows to store any character as number in range [0, 255] as well as to return EOF (usually -1) in case of failure.

So, with getc() it would look like:

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

Note:

You may assign read to a variable of type char – it will be implicitly converted. In case of getc() succeeded, there shouldn't be any data loss in this implicit conversion.


A little sample to show this at work:

#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;
}

Note:

The read characters are stored in buffer without a termination '\0'. This is handled in printf() respectively by the formatter %.*s meaning string with max. width * where width and string are read as consecutive arguments.

Live Demo on ideone




回答2:


Your

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

is a typing mistake : the types of left and right operands to != don't match. Read about type systems.

Read the documentation of scanf. It says that scanf returns some int value.

But NULL is a pointer value (it is (void*)0).

How can a pointer be meaningfully compared to an int? On my Debian/x86-64, they don't even have the same size (as returned by sizeof): a pointer takes 8 bytes but an int takes 4 bytes.

So the compiler is right in warning you.

You probably want to code instead something like while (scanf("%c", &read) >0) or even while (scanf("%c", &read) == 1) since for a successful scan of "%c" the scanf function is documented to give 1.

Of course, in that particular case, using fgetc is better (more readable, and probably slightly faster). Read documentation of fgetc and follow the advice given by Sheff's answer.

Next time:

  • be sure to read the documentation of every function that you are using. Never use a function whose documentation you have not read and understood.

  • ask the compiler to give all warnings and debug info, so with GCC compile with gcc -Wall -Wextra -g. Trust your compiler, and improve your code to get no warnings at all.

  • read How To Debug Small Programs.

  • read the documentation of gdb (and perhaps of valgrind).

  • study, for inspiration, the source code of some small free software similar to yours (perhaps on github).

PS. Naming your variable read is poor taste. For most people it conflicts with the POSIX read function.



来源:https://stackoverflow.com/questions/52233657/why-does-comparing-the-result-of-scanf-with-null-generate-a-compiler-warning

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!