0

Why does the program enter infinite loop when I input EOF (Ctrl-D)?

    #include  <stdio.h>
    
    main()
    {
            int c = EOF ;
    
            while(c==EOF)
            {
                    printf("input value c=%d \n",c);
                    printf("EOF=%d \n",EOF);
                    c = getchar();  //expect the while loop to pause here and wait for input
    
            }
    
            printf("the value of last input c=%d \n",c);
    
    }

When I enter any other character the program exits immediately as expected. But when I enter EOF (Ctrl-D) I expect the program to reiterate within the while loop and wait for the next user input with getchar.

Update: I read the manual pages for the shell this program runs in manpage for GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)

Commands for Changing Text
       end-of-file (usually C-d)
              The  character  indicating  end-of-file  as set, for example, by ``stty''.  If this character is read
              when there are no characters on the line, and point is at the beginning of the line, Readline  inter‐
              prets it as the end of input and returns EOF.

I think what is happening is that when I enter EOF as input the shell no longer passes input to program so program just skips the line c=getchar(); and repeats the loop. Any further insights will be appreciated.

5
  • Have you tried adding clearerr(stdin); at the start of your loop? I can't reproduce your problem (on Windows) but maybe, on your platform, the EOF flag prevents getchar from attempting further input operations. Commented Jan 15, 2021 at 3:01
  • What do you want to do? Once getchar returns EOF [from entering ctrl-D], it will continue to do so. After getchar [as Adrian suggested], if you do: if (c == EOF) clearerr(stdin);, it will work as you're intending: if you then enter j\n [you need the newline to get the kernel tty layer to send the chars], you'll get the j. It is not the shell that is controlling input, it is the kernel tty driver/layer. But, why? The usual is: while (1) { c = getchar(); if (c == EOF) break; process_char(c); } Commented Jan 15, 2021 at 3:13
  • @CraigEstey "Once getchar returns EOF, it will continue to do so" does have a rare exception: When EOF returned due to input error, a subsequent call may not return EOF - depends on the error. Commented Jan 15, 2021 at 3:17
  • @chux-ReinstateMonica For non-tty input, that's probably true. But, OP is talking about tty input and the only way [that I can think of] to get an error is to send a signal to the process or kill the containing terminal emulator. But, it's looking more like an XY problem. For OP: meta.stackexchange.com/questions/66377/what-is-the-xy-problem Commented Jan 15, 2021 at 3:25
  • A more orthodox while loop would be while ((c = getchar()) != EOF) { … } with no need for getchar() inside the loop. That doesn't do quite the same job, but it is probably more useful in the long run. Commented Jan 15, 2021 at 5:33

1 Answer 1

1

Why does the program enter infinite loop when I input EOF (Ctrl-D)?

Once the file is closed due to OP's CtrlD, getchar() does not wait for anything and just returns EOF as the end-of-file indicator is set.

7.21.7.6 The getchar function
If the stream is at end-of-file, the end-of-file indicator for the stream is set and getchar returns EOF.

To make getchar() wait for another character, clear the end-of-file indicator. Perhaps with clearerr() (@Adrian Mole) which clears both the error and end-of-file indicator.


when I enter EOF as input the shell no longer passes input to program so program just skips the line c=getchar();

I'd say the getchar(), when the end-of-file indicator is set, does not call the shell for more data and simply returns EOF. Details are implementation specific.

Sign up to request clarification or add additional context in comments.

1 Comment

clearerr(stdin) clears the end-of-file indicator . Program know works as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.