Resetting stdin after EOF (C)


Results 1 to 3 of 3

Thread: Resetting stdin after EOF (C)

  1. #1
    Join Date
    Aug 2002
    Location
    Essex, UK
    Posts
    937

    Resetting stdin after EOF (C)

    I have a piece of code that looks like this:

    ---example.c---

    Code:
    #include <stdio.h>
    
    int main() {
            char c;
            while ((c = getchar()) && (c != EOF))
                    ;
            putchar('\n');
            c = getchar();
            printf("%c\n", c);
    }
    Entering input from the keyboard, this program works fine.
    However, if I then redirect input to this program (e.g. dmesg | ./example), then I get a garbage character printed to the console, and the program does not wait for input from the keyboard.
    I assume this is something to do with resetting stdin - how can I pass input back to the keyboard?

    Thanks,
    Rob
    Registered Linux User #325947

    Check out Feather Linux, my distro.
    (Yes, it's shameless self promotion, deal with it )

  2. #2
    Join Date
    Apr 2001
    Location
    SF Bay Area, CA
    Posts
    14,947
    Um.... getchar() returns an int, not a char. Your loop will terminate early if your input ever has a byte with value 255 in it (EOF, or -1, cast to a char, has value 255).

    You need to declare c as an int, and check it against EOF as an int. Only after you've determined that it isn't EOF, is it safe to cast it to a char.

    However, if I then redirect input to this program (e.g. dmesg | ./example), then <...> the program does not wait for input from the keyboard.
    That's exactly how it's supposed to work

    When input is coming from another command instead of the keyboard, your program can't wait for the user to press a key when your program is finished. It has no way of talking to the keyboard.

    I also believe that reading characters after you've hit EOF is explicitly undefined (i.e., anything can happen and it'll still be a legal C implementation), though I might be wrong on that. If you were reading from a normal file, you'd be able to fseek backwards to "reset" the file handle, but stdin is un-seekable, so that won't work either.

    So I'm not sure what you were trying to accomplish here, but there's probably a better way to do it.

  3. #3
    Join Date
    Aug 2002
    Location
    Essex, UK
    Posts
    937
    Unfortunately not - the program I gave was just a simple example to illustrate the problem, rather than what I actually needed.
    I found a solution, though it isn't portable:

    fclose(stdin);
    inp = fopen(CURRENT_TTY, "r");
    c = getc(inp);

    does the trick, though it's not too nice. Thanks anyway.
    Registered Linux User #325947

    Check out Feather Linux, my distro.
    (Yes, it's shameless self promotion, deal with it )

Posting Permissions

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