tags:

views:

115

answers:

5
#include <stdio.h>

int main() {
    char read = ' ';

    while ((read = getchar()) != '\n') {
        putchar(read);
    }

    return 0;
}

My input is f (followed by an enter, of course). I expect getchar() to ask for input again, but instead the program is terminated. How come? How can I fix this?

+1  A: 

after f you are putting "enter" which is '/n'. so the loop ends there. if you want to take another character just keep on putting them one after the other as soon as enter is pressed the loop exits.

CadetNumber1
+1  A: 

You've programmed it so the loop ends when you read a \n (enter), and you then return 0; from main which exits the program.

Perhaps you want something like

 while ((read = getchar()) != EOF) {
        putchar(read);
    }
nos
I've tried that, but this creates an infinite loop. I'm a Windows user, by the way.
Pieter
You have to declare the 'read' variable as int, not char - else you might very well get an infinite loop. It should exit if you kill it with CTRL+C, or end the input with CTRL+Z. When do you want your program to end ?
nos
+2  A: 

getchar() returns the next character from the input stream. This includes of course also newlines etc. The fact that you don't see progress in your loop unless you press 'Enter' is caused by the fact that your file I/O (working on stdin) doesn't hand over the input buffer to getchar() unless it detects the '\n' at the end of the buffer. Your routine first blocks then handles the two keystrokes in one rush, terminating, like you specified it, with the appearance of '\n' in the input stream. Facit: getchar() will not remove the '\n' from the input stream (why should it?).

slartibartfast
+5  A: 

The Terminal can sometimes be a little bit confusing. You should change your program to:

#include <stdio.h>

int main() {
    int read;
    while ((read = getchar()) != EOF) {
        putchar(read);
    }
    return 0;
}

This will read until getchar reads EOF (most of the time this macro expands to -1) from the terminal. getchar returns an int so you should make your variable 'read' into an integer, so you can check for EOF. You can send an EOF from your terminal on Linux with ^D and I think on windows with ^Z (?).

To explain a little bit what happens. In your program the expression

(read = getchar()) !='\n'

will be true as long as no '\n' is read from the buffer. The problem is, to get the buffer to your program, you have to hit enter which corresponds to '\n'. The following steps happen when your program is invoked in the terminal:

~$\a.out

this starts your program

(empty line)                    

getchar() made a system call to get an input from the terminal and the terminal takes over

f                   

you made an input in the terminal. The 'f' is written into the buffer and echoed back on the terminal, your program has no idea about the character yet.

f
f~$                 

You hit enter. Your buffer contains now 'f\n'. The 'enter' also signals to the terminal, that it should return to your program. Your progam reads the buffer and will find the f and put it onto the screen and then find an '\n' and immediatley stop the loop and end your program.

This would be standard behaviour of most terminals. You can change this behaviour, but that would depend on your OS.

Lucas
Can I do something like `fflush(stdin);` to display the input without pressing enter?
Pieter
@Pieter: no. You have to change your terminal into non-canonical mode (terminal input is processed line by line in canonical mode). But that is not OS independent.
Lucas
A: 

On *n*x terminals you can press Control-D which will tell the tty driver to return the input buffer to the app reading it. That's why ^D on a new line ends input - it causes the tty to return zero bytes, which the app interprets as end-of-file. But it also works anywhere on a line.

Bernd Jendrissek