Results 1 to 8 of 8

Thread: silly question about infinite loop

  1. #1

    Default silly question about infinite loop

    #include <stdio.h>
    int main(){
    char c;
    while(1){
    printf("Enter your choice\n");
    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.

  2. #2
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: silly question about infinite loop

    Cross_AM wrote:

    > #include <stdio.h>
    > int main(){
    > char c;
    > while(1){
    > printf("Enter your choice\n");
    > 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\n");
    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'\n",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

  3. #3
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: silly question about infinite loop

    L R Nix wrote:

    > Cross_AM wrote:
    >
    >> #include <stdio.h>
    >> int main(){
    >> char c;
    >> while(1){
    >> printf("Enter your choice\n");
    >> 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\n");
    > 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'\n",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\n");
    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 \n in there somewhere too... like this:

    printf("Enter your choice: ");
    c=getchar();
    printf("\n");
    printf("You pressed '%c'\n",c);

    aaaaannnd, now I'm rambling.

    Hope that helps.


    --
    L R Nix
    lornix@lornix.com

  4. #4
    Rikishi 42 NNTP User

    Default Re: silly question about infinite loop

    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\n");
    > 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

  5. #5
    Join Date
    Jun 2008
    Location
    Freiburg, Germany
    Posts
    32

    Default Re: silly question about infinite loop

    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\n");
    scanf("&#37;c", &c);
    while((b = getchar()) != EOF && b != '\n');
    }
    return 0;
    }
    Last edited by KelloggsFrosties; 30-Jul-2008 at 01:16. Reason: Added ExampleCode

  6. #6
    Join Date
    Jun 2008
    Location
    UTC+10
    Posts
    9,686
    Blog Entries
    4

    Default Re: silly question about infinite loop

    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.

  7. #7

    Default Re: silly question about infinite loop

    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.

  8. #8

    Default Re: silly question about infinite loop

    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.



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •