'while ((c = getchar()) != EOF) Not terminating

I've been reading "The C Programming Language" and I got to this part of inputs and outputs.

I've read other threads saying that the console doesn't recognize enter as EOF. So that I should use CTRL + Z in Windows or CTRL + D in Unix (neither of those is working for me).

I also read other people asking the same saying they could make it work, the problem in their codes was syntax not the program not terminating.

Is there another solution?

This is the code:

#include <stdio.h>

main()
{
    int nb, nl, nt, c;
    nb = 0;
    nl = 0;
    nt = 0;
    while ((c = getchar()) != '\n') {
        if (c == ' ')
            ++nb;
        else if (c == '\n')
            ++nl;
        else if (c == '\t')
            ++nt;
    }
    printf("Input has %d blanks, %d tabs, and %d newlines\n", nb, nt, nl);
}

Edit: The \n was supposed to be an EOF, I was messing around before I posted and I forgot I changed it :P

It doesn't work with EOF neither, I just skipped that one.



Solution 1:[1]

while ((c = getchar())  !=EOF) {


}

Then use Ctrl+Z or F6 on Windows

Following will wait for either a \n or EOF, which comes first

while((c = getchar()) != '\n' && c != EOF){

}

Solution 2:[2]

On Windows, you type Ctrl-Z on a line by itself (no spaces or anything) and type the Return after that. On Windows, you could technically skip the EOF indicator and keep reading characters, though this doesn't apply to other operating systems because EOF actually means EOF.

Solution 3:[3]

while ((c = getchar()) != '\n'){
    if (c == ' ')
        ++nb;
    else if (c == '\n')
        ++nl;
    else if (c == '\t')
        ++nt;
} 

According to the condition in your while loop, you will not be able to count number of new lines because you will stop the while loop when the user inputs a new line character ('\n')

Other than that, counting blanks and tabs just works fine.

CTRL+Z will be recognized as a EOF in windows. But in order to recognize it in your program, use condition in while loop as ((c = getchar()) != EOF). Now when the user presses the key combination: CTRL+Z, It will input to console as EOF, and the program should recognize it as a character input.

Doing this will allow you to count number of lines in the input

So, my suggestion is:

while ((c = getchar()) != EOF){
    if (c == ' ')
        ++nb;
    else if (c == '\n')
        ++nl;
    else if (c == '\t')
        ++nt;
} 

Solution 4:[4]

If you are on unix system:

The only way to simulate EOF via keyboard while feeding input to the program manually is to press CTRL+D

Here are a couple methods of feeding input to your program and be able to signal EOF at the end of the input:

  • Make use of the here string format to feed a string representation of a file to the program.
./myprog <<< "Here is a string to work with"
  • Alternatively, you can also use input redirection to feed a file containing the input to the program.
./myprog < input.file

Any of the above listed methods will work with the following code:

#include <stdio.h>
#ifndef EOF
#define EOF (-1)
#endif
int main(void)
{
    int nb, nl, nt, c;
    nb = 0;
    nl = 0;
    nt = 0;
    while ((c = getchar()) != EOF){
        if (c == ' ')
            ++nb;
        else if (c == '\n')
            ++nl;
        else if (c == '\t')
            ++nt;
    }
    printf("Input has %d blanks, %d tabs, and %d newlines\n", nb, nt, nl);
    return 0;
}
  • Not to leave windows out of the game. To simulate EOF on keyboard on windows, use CTRL+Z key combination

Not sure if the here-string format for unix is available for windows, but input redirection should be similar

Solution 5:[5]

    /* This program will calculate the number of blanks, tabs and new line in a text stream */

#include <stdio.h>

main () 
{
    int c,nl = 0, blank = 0, tab = 0; //Newline, blanks and tabs.
    while ((c = getchar()) != EOF) {
        if (c == '\n')
            ++nl;
        else if (c == '\t')
            ++tab;
        else if (c == ' ')
            ++blank;
}
    printf("Tabs = %d\nBlanks = %d\nNewLine = %d",tab, blank, nl);
}

I wrote this following code and it works properly on Ubuntu. As it is similar to what you wrote, I tried the code and Ctrl-D is working properly in UNIX.

I tested the following code and have realized that if we input \n in text stream it will not increase the counter of the new line, same goes for a \t tab. Only pressing enter for new line and pressing tab for tab is counted by the counter this is a point to be noted.

This is happening because pressing enter actually puts a newline character which is a single character whereas entering \n is treated as differently and they are actually two characters.

I thought this will add value to this question so I explained this thing too. Thanks.

Solution 6:[6]

Change the line

// Buggy, you want calculate the # of '\n' in loop body,
// so logically you shouldn't use it as a stop condition.
while ((c = getchar()) != '\n')

to

while ((c = getchar()) != EOF)

And try press Ctrl + C in your console window on Windows. It works on my platform which is running Win7.

enter image description here

Solution 7:[7]

First of all press Ctrl + Z which will print ^Z then press Enter to go to EOF..

Solution 8:[8]

I had the same problem, so I check the value of ctrl+D by debugging my code and I found that the value of ctrl+D is 255 and I replaced the EOF with 255, and thats worked for me, if its not working for you try to figure out the value of ctrl + D in Unix.

#include <stdio.h>

main()
{
    int nb, nl, nt, c;
    nb = 0;
    nl = 0;
    nt = 0;
    while ((c = getchar()) != 255) {
        if (c == ' ')
            ++nb;
        else if (c == '\n')
            **++nl;**
        else if (c == '\t')
            ++nt;
    }
    printf("Input has %d blanks, %d tabs, and %d newlines\n", nb, nt, nl);
}

Solution 9:[9]

To recognize EOF in Turbo C++, in the terminal window press Ctrl+z; this will act as EOF in the program and then terminate the program....with the condition:

while ((c = getchar()) != EOF) 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 P0W
Solution 2
Solution 3 smac89
Solution 4
Solution 5 Darshit Mulani
Solution 6
Solution 7 Keshan Nageswaran
Solution 8 Chris
Solution 9 Jonathan Leffler