-
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 )
-
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.
-
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
-
Forum Rules
|
|