1
#include <stdio.h>

main() {
long nc;

nc = 0;
while (getchar() != -1)
    ++nc;
printf("%ld\n", nc);
}

Above is my code from K&R C book for example 1.5.2 but I changed the code so getchar() is checking for -1. However when typing in negative one (-1) the code does not stop reading in getchar(). How do I get the code to stop and why is it not stopping?

Jinzu
  • 1,325
  • 2
  • 10
  • 22
  • 3
    ... you are not supposed to *type* `-1` ... It's the `EOF` code as explained in [just about every description](http://www.cplusplus.com/reference/cstdio/getchar/). – Jongware Dec 17 '17 at 00:11
  • 2
    Behold, `-1` is two characters. `getchar()` would first return `-` (45), then `1` (49). – melpomene Dec 17 '17 at 00:12
  • 1
    `getchar()` gets, well, a `char` - a single character. That's why it can't read "-1", a string of 2 characters – Ben Kolya Mansley Dec 17 '17 at 00:12
  • 1
    Fixed by either using `EOF` or a single character of your choice – Ben Kolya Mansley Dec 17 '17 at 00:12
  • 1
    At a terminal, you can indicate EOF by typing a suitable character, usually control-D on Unix and control-Z on Windows. If you didn't type newline (return) before that, you will need to hit the control character twice. There's a reason, of course, but it is fiddly to explain. – Jonathan Leffler Dec 17 '17 at 00:33

1 Answers1

3

The getchar() function reads a single byte from stdin, and returns the value of that byte. For example, on an ASCII based system, the byte value 32 represents a space, the value 33 represents an exclamation point (!), the value 34 represents a double quote ("), and so on. In particular, the characters - and 1 (which make up the string "-1") have the byte values 45 and 48 respectively.

The number -1 does not correspond to any actual character, but rather to the special value EOF (an acronym for end of file) that getchar() will return when there are no more bytes to be read from stdin. (Actually, the EOF value is not guaranteed by the C standard to be equal to -1, although on most systems it is. It is guaranteed to be less than zero, though.)

So your loop, as written, will continue to run until there's no more input to be read. If you're running your code from a terminal, that basically means it will keep running until you type Ctrl+D (on Unixish systems) or Ctrl+Z (on Windows). Alternatively, you could run your program with its input coming from a file (e.g. with my_program < some_file.txt), which would cause the loop to run until it has read the entire file byte by byte.

If you instead want to read a number from stdin, and loop until the number equals -1, you should use scanf() instead.

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153