silly question about infinite loop

#include <stdio.h>
int main(){
char c;
while(1){
printf(“Enter your choice
“);
scanf(”%c”, &c);

}
return 0;
}

This was the code I compiled. I wanted it to print the line and ask for
input but the result was something like the following

Enter your choice
y
Enter your choice
Enter your choice
y
Enter your choice
Enter your choice
y
Enter your choice
Enter your choice
y
Enter your choice
Enter your choice
y
Enter your choice
Enter your choice
y
Enter your choice
Enter your choice
y
Enter your choice
Enter your choice

Please explain why two lines are coming.

Cross_AM wrote:

> #include <stdio.h>
> int main(){
> char c;
> while(1){
> printf(“Enter your choice
“);
> scanf(”%c”, &c);
>
> }
> return 0;
> }
>
> This was the code I compiled. I wanted it to print the line and ask for
> input but the result was something like the following
>
> Enter your choice
> y
> Enter your choice
> Enter your choice

>
> Please explain why two lines are coming.

You’ve asked scanf to read a single character (%c) at a time. So it reads
the ‘Y’, and then the ‘ENTER’ after it. And the system doesn’t give your
input to scanf until you press ENTER… it sees two characters. I imagine
if you were to type a long line, you’d get a string of “Enter your choice”
prompts running down the screen, one for each letter!

If you want to read a whole line, you’ll need to have room for it (“char c”
only defines a single character’s worth of space), and tell scanf to read a
line (%s)

** Note ** scanf is not very friendly, and can contribute to buffer overruns

A better function to use is fgets, as it allows you to read an entire ‘line’
of input, and has a maximum limit on how much it’ll grab, helping to
prevent buffer overrun errors. (very bad things!)

Try something like this:

(Guys, don’t flame me, I’m working on the KISS principle here!)

#include <stdio.h>
int main(){
char line[81]; /* extra for \0 at end /
while(1){
printf("Enter your choice
");
fgets(line,80,STDIN);
/
your input will be in ‘line’ array /
/
and is limited to 80 chars maximum /
/
you can set max chars to anything

  • just remember to make sure there’s
  • room reserved for it */
    printf("You typed ‘%s’
    ",line);
    }
    return 0;
    }

Admittedly, there are better ways to do this, but as a starting point…
you’re doing great. Good luck.


L R Nix
lornix@lornix.com

L R Nix wrote:

> Cross_AM wrote:
>
>> #include <stdio.h>
>> int main(){
>> char c;
>> while(1){
>> printf(“Enter your choice
“);
>> scanf(”%c”, &c);
>>
>> }
>> return 0;
>> }
>>
>> This was the code I compiled. I wanted it to print the line and ask for
>> input but the result was something like the following
>>
>> Enter your choice
>> y
>> Enter your choice
>> Enter your choice
>
>>
>> Please explain why two lines are coming.
>
> You’ve asked scanf to read a single character (%c) at a time. So it reads
> the ‘Y’, and then the ‘ENTER’ after it. And the system doesn’t give your
> input to scanf until you press ENTER… it sees two characters. I imagine
> if you were to type a long line, you’d get a string of “Enter your choice”
> prompts running down the screen, one for each letter!
>
> If you want to read a whole line, you’ll need to have room for it (“char
> c” only defines a single character’s worth of space), and tell scanf to
> read a line (%s)
>
> ** Note ** scanf is not very friendly, and can contribute to buffer
> overruns
>
> A better function to use is fgets, as it allows you to read an entire
> ‘line’ of input, and has a maximum limit on how much it’ll grab, helping
> to prevent buffer overrun errors. (very bad things!)
>
> Try something like this:
>
> (Guys, don’t flame me, I’m working on the KISS principle here!)
>
> #include <stdio.h>
> int main(){
> char line[81]; /* extra for \0 at end /
> while(1){
> printf("Enter your choice
");
> fgets(line,80,STDIN);
> /
your input will be in ‘line’ array /
> /
and is limited to 80 chars maximum /
> /
you can set max chars to anything
> * just remember to make sure there’s
> * room reserved for it */
> printf("You typed ‘%s’
",line);
> }
> return 0;
> }
>
> Admittedly, there are better ways to do this, but as a starting point…
> you’re doing great. Good luck.
>
>

Duh, replying to my own post too… I’m SUCH a blonde!

I just realized you might want to only read a single character… looks like
a menu prompt.

So this:

#include <stdio.h>
int main(){
int c; /* use ‘int’ to read characters */
while(1){
printf("Enter your choice
");
c=getchar();
}
return 0;
}

Is probably more what you’re looking for.

The reason you need ‘c’ to be an ‘int’ instead of a ‘char’ is that ANY input
function can return EOF, which technically is ‘-1’, but could be anything
really. EOF is usually out-of-range for a char variable, which can’t
represent the EOF and thus converts it to a char… meaning you would never
SEE an EOF… which is a real bummer when you’re actually looking for it.

You’ll probably want a
in there somewhere too… like this:

printf("Enter your choice: “);
c=getchar();
printf(”
");
printf("You pressed ‘%c’
",c);

aaaaannnd, now I’m rambling.

Hope that helps.


L R Nix
lornix@lornix.com

On 2008-07-28, Cross_AM <Cross_AM@no-mx.forums.opensuse.org> wrote:
> #include <stdio.h>
> int main(){
> char c;
> while(1){
> printf(“Enter your choice
“);
> scanf(”%c”, &c);
>
> }
> return 0;
> }
>
> This was the code I compiled. I wanted it to print the line and ask for
> input but the result was something like the following
>
> Enter your choice
> y
> Enter your choice
> Enter your choice
> y

> Please explain why two lines are coming.

Probably because you’re scanning to a char, not to a string.
The char is 1 char long, of course. So when the ‘y’ is typed, the scan is
complete, the loop is run again, this time to capture your <enter>.

Not sure, but defining
char *c
might be better.

could be something else, too. I’ve been out of C for a long time.


The sand remembers once there was beach and sunshine
but chip is warm too
– haiku from Effector Online, Volume 1, Number 6

It is because of the keyboard buffer. In your program scanf() reads only one character from the keyboardbuffer, but you have entered at least two characters (y and /n) and therefore it can take two characters from the keyboard buffer.

Better use getc() which doesn’t wait for EOF or /n and really returns just one character. Or save scanf() to a stringbuffer an search the needed character in this one.

Another idea would be, to empty the keyboard buffer after every scanf by doing as follows:

#include <stdio.h>

int main()
{
char c;
char b;
while(1)
{
printf(“Enter your choice
“);
scanf(”%c”, &c);
while((b = getchar()) != EOF && b != ’
');
}
return 0;
}

There are a couple of things to keep in mind:

getchar and getc should be assigned to int, not char. As lornix has explained, EOF is -1 but this is the same as the char with code 255 in 8 bits. Char code 255 could be entered, though unlikely, and would be indistinguishable from EOF. To represent 256 values plus EOF, you need a larger type, i.e. not char, but int.

The normal mode of console input is line oriented, which means data is not available until an end-of-line has been entered (CR on the keyboard, mapped to NL in the input buffer. So you should flush the rest of the line if you are reading only one char. Or read a whole line at a time.

For apps that need to read a char at a time and react immediately there is raw mode and cooked mode for the tty device. But that’s an answer to a different question.

L R Nix wrote:

> I just realized you might want to only read a single character… looks
> like a menu prompt.
Well thank you for the input. I wanted that only. And thanks for reminding
me of EOF.
I figured out that
scanf(" %c", &c);
does the job for me.

ken yap wrote:

> Char code 255 could be entered, though unlikely, and would be
> indistinguishable from EOF.
Your inputs have been very valueable ken.Thanks.

> The normal mode of console input is line oriented, which means data is
> not available until an end-of-line has been entered (CR on the
> keyboard, mapped to NL in the input buffer. So you should flush the
> rest of the line if you are reading only one char. Or read a whole line
> at a time.

I tried flushing but it didn’t work.However,
scanf(" %c", &c);
has done it for me.