codenoob
codenoob

Reputation: 111

"Count characters" program: While loop not terminating on EOF

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

Upvotes: 1

Views: 666

Answers (3)

anastaciu
anastaciu

Reputation: 23822

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

Upvotes: 2

Pavel
Pavel

Reputation: 82

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

Upvotes: 2

Lee Daniel Crocker
Lee Daniel Crocker

Reputation: 13171

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.

Upvotes: 2

Related Questions