1
votes

Following "The C Programming Language" by Kernighan and Ritchie, I am trying to enter the program described on page 18 (see below).

The only changes I made were to add "int" before "main" and "return 0;" before closing the brackets.

When I run the program in Terminal (Mac OS 10.15) I am prompted to enter an input. After I enter the input I am prompted to enter an input again - the "printf" line is apparently never reached and so the number of characters is never displayed.

Can anyone help me with the reason why EOF is never reached letting the while loop exit? I read some other answers suggesting CTRL + D or CTRL + Z, but I thought this shouldn't require extra input. (I was able to get the loop to exit with CTRL + D).

I have also pasted my code and the terminal window below.

#include <stdio.h>
int main(){

    long nc;

    nc = 0;
    while( getchar() != EOF )
        ++nc;

    printf("%ld\n", nc);

    return 0;
}

From pg. 18 of "The C Programming Language

Image from pg. 18 of "The C Programming Language"

My screenshot

My Terminal and code screenshot

3
The screen shot shows you stopped the program with Ctrl-C not with Ctrl-D as stated.Weather Vane
Sorry bout that - updated pic to include both scenarios. On an unrelated question I was wondering why the letter D is included when the number of characters is fewer than 10 - but if that's another topic then never mind.codenoob
You have nothing in your code to prompt for input. Have you thought about echo "count these characters" | ./count? Or ./count < somefile?David C. Rankin
Haven't even learned how to use those methods yet, I was just following the suggested program in the book for now. Thanks for the tip!codenoob

3 Answers

2
votes

You already have the correct answer: when entering data at the terminal, Ctrl-D is the proper way to indicate "I'm done" to the terminal driver so that it sends an EOF condition to your program (Ctrl-Z on Windows). Ctrl-C breaks out of your program early.

If you ran this program with a redirect from an actual file, it would properly count the characters in the file.

2
votes

EOF means end of file; newlines are not ends of files. You need to press CTRL+D to give the terminal an EOF signal, that's why you're never exiting your while loop.

If you were to give a file as input instead of through the command line, then you would not need to press CTRL+D

1
votes

Adding to the two good answers I would stress that EOF does not naturally occur in stdin like in other files, a signal from the user must be sent, as you already stated in your question.

Think about it for a second, your input is a number of characters and in the end you press Enter, so the last character present in stdin is a newline character not EOF. For it to work EOF would have to be inputed, and that is precisely what Ctrl+D for Linux/Mac or Ctrl+Z for Windows, do.

As @DavidC.Rankin correctly pointed out EOF can also occur on stdin through bash piping e.g. echo "count this" | ./count or redirecting e.g. ./count < somefile, where somefile would be a text file with the contents you want to pass to stdin.

By the way Ctrl+C just ends the program, whereas Ctrl+D ends the loop and continues the program execution.

For a single line input from the command line you can use something like:

int c = 0;

while((c = getchar()) != EOF && c != '\n'){
    ++nc;
}