From: Eric Sosman on 28 Feb 2010 18:29 On 2/28/2010 6:16 PM, Poster Matt wrote: > [...] > int GetUserConfirmation(void) > { > printf("\nAre all the settings and options correct?\n" \ > "Do you want to proceed? (Y = Yes, N = No): "); > > // Was using: > //char c = (char) getchar(); > > // Now using - has the same effect. > int c = getchar(); Elsewhere you've ensured that stdin takes data from something that is not a tty (you're assuming it's reading from a file, but it might be a socket or a pipe or some such -- but in any case, it is *not* reading the keyboard). For ten points: From what stream does getchar() read its character? For ten more points: If getchar()'s input stream is not reading from a keyboard, can getchar() read from a keyboard? For yet another ten points (and and a share of the lead): What does getchar() return if it cannot obtain a character from its input stream? For still another ten points (and sole possession of first place!): Does getchar() *always* return an input character? For ONE HUNDRED POINTS (and an Olympic gold medal): Is the comp.lang.c Frequently Asked Questions (FAQ) list at <http://www.c-faq.com/> in your bookmarks list? -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: yooooooooooooo on 1 Mar 2010 05:54 On Mar 1, 5:56 am, Poster Matt <postermatt(a)no_spam_for_me.org> wrote: > Hi, > > My code allows a user to redirect a file to stdin so that some text data can be > read, no problem. > > Later a user confirmation to proceed is requested, using getchar(). This is not > working because of what's left in stdin. > > Initially I was actually stopping reading stdin when some specific data being > searched for was located, ignoring what was left in stdin. When I realized what > was happening, I made sure I continued reading stdin all the way through. > > The problem seems to be that my user confirmation call to getchar() receives the > following char: 'ÿ'. I looked in the ASCII table and it is the final char, 255 > or FF. But I have no idea what this is or why it's there. > > I've tried reading stdin through to the end with fgets... > > while (fgets(buffer, maxLineLen, stdin) != NULL) > check line for what I want; > > ...and also with scanf (just reading %s): > > while (scanf("%s", buffer) != EOF) > check line for what I want; > > but I always the get the 'ÿ' char when it comes to my user confirmation.. > > The faq suggests trying the following code: > > while((c = getchar()) != '\n' && c != EOF) > /* discard */ ; > > No luck, I still get 'ÿ'. > > I even tried calling fgets and scanf immediately before calling getchar and > printfing what was got - but there is nothing to printf - and yet 'ÿ' is still > there to sabotage the call to getchar(). > > Even though the faq warns against it, I even tried fflush(stdin). Nope. :( > > What is this little fellow, 'ÿ'. Why's it there? How can I get rid of it? > > I should mention that if I do not redirect a file to stdin on the command line, > the user confirmation works fine, no sign at all of 'ÿ'. > > Many thanks. I assume that EOF is usually implemented as -1 of int type. This may be the key point. Hope this can help you.
From: Poster Matt on 1 Mar 2010 09:16 Thanks for replying Eric and forcing me to follow a logical problem resolution process. Eric Sosman wrote: > > For ten points: From what stream does getchar() read > its character? stdin - Score: 10. > For ten more points: If getchar()'s input stream is not > reading from a keyboard, can getchar() read from a keyboard? No - Score: 20. > For yet another ten points (and and a share of the lead): > What does getchar() return if it cannot obtain a character > from its input stream? EOF, on my system that equates to char 'ÿ' (BINGO!). Score 30. > For still another ten points (and sole possession of > first place!): Does getchar() *always* return an input > character? No - Score: 40. > For ONE HUNDRED POINTS (and an Olympic gold medal): Is > the comp.lang.c Frequently Asked Questions (FAQ) list at > <http://www.c-faq.com/> in your bookmarks list? Yes - Score 140 + Olympic Gold, in an event with no other competitors. :) > Elsewhere you've ensured that stdin takes data from > something that is not a tty (you're assuming it's reading > from a file, but it might be a socket or a pipe or some > such -- but in any case, it is *not* reading the keyboard). Agreed, but I have not done that explicitly in my code. I've investigated what's happening with ttyname. "The ttyname() function returns a pointer to a string containing a null-terminated pathname of the terminal associated with file descriptor fildes." If I make this call in the program: ttyname((fileno(stdin))); having run my program with a file redirected to stdin on the command line IE. 'program < file.txt' then NULL is returned by ttyname - stdin is not a terminal device. If there's no file redirected on the command line then /dev/pts/6 is returned by ttyname - that must be the terminal through which a user's key input can be read. I didn't fully understand how stdin worked, assuming, without understanding, that stdin would be fed a file redirected from the command line and then revert to a terminal device once there's no more input from the redirected file. The problem is now how do I achieve that behaviour? When the program starts, check if there's been a file redirected from the command line, if so read that file storing relevant data, then -either way- make sure I can read a character entered by the user from the terminal/keyboard to give confirmation that proceeding is ok? I've got a much better understanding of stdin now, but for the life of me can't work out how to do this. Thanks and regards, and apologies for my amateurishness.
From: Ben Bacarisse on 1 Mar 2010 09:38 Poster Matt <postermatt(a)no_spam_for_me.org> writes: > Eric Sosman wrote: <snip> >> For yet another ten points (and and a share of the lead): >> What does getchar() return if it cannot obtain a character >> from its input stream? > > EOF, on my system that equates to char 'ÿ' (BINGO!). This "equates to" hides too many details to leave it like that. It may be true that EOF == 'ÿ' but when getchar returns a character from its stream, the character has been converted to an unsigned char and it is that value that forms the int returned by getchar. As a result getchar() == EOF can not be made to be true by reading a 'ÿ' from the input. This is why the result of getchar should be stored in an int rather than a char variable. Using a char variable throws away this extra information -- the distinction between a valid input character (always positive) and EOF (some negative int). I sounds like you've "got" this. I add it simply in case someone reading this concludes that, on some systems, 'ÿ' can't be distinguished from EOF on input. <snip> -- Ben.
From: Poster Matt on 1 Mar 2010 09:48 Poster Matt wrote: > Thanks for replying Eric and forcing me to follow a logical problem > resolution process. > > Eric Sosman wrote: >> >> For ten points: From what stream does getchar() read >> its character? > > stdin - Score: 10. > >> For ten more points: If getchar()'s input stream is not >> reading from a keyboard, can getchar() read from a keyboard? > > No - Score: 20. > >> For yet another ten points (and and a share of the lead): >> What does getchar() return if it cannot obtain a character >> from its input stream? > > EOF, on my system that equates to char 'ÿ' (BINGO!). Score 30. > >> For still another ten points (and sole possession of >> first place!): Does getchar() *always* return an input >> character? > > No - Score: 40. > >> For ONE HUNDRED POINTS (and an Olympic gold medal): Is >> the comp.lang.c Frequently Asked Questions (FAQ) list at >> <http://www.c-faq.com/> in your bookmarks list? > > Yes - Score 140 + Olympic Gold, in an event with no other competitors. :) > > > Elsewhere you've ensured that stdin takes data from > > something that is not a tty (you're assuming it's reading > > from a file, but it might be a socket or a pipe or some > > such -- but in any case, it is *not* reading the keyboard). > > Agreed, but I have not done that explicitly in my code. I've > investigated what's happening with ttyname. > > "The ttyname() function returns a pointer to a string containing a > null-terminated pathname of the terminal associated with file descriptor > fildes." > > If I make this call in the program: > > ttyname((fileno(stdin))); > > having run my program with a file redirected to stdin on the command > line IE. 'program < file.txt' then NULL is returned by ttyname - stdin > is not a terminal device. > > If there's no file redirected on the command line then /dev/pts/6 is > returned by ttyname - that must be the terminal through which a user's > key input can be read. > > I didn't fully understand how stdin worked, assuming, without > understanding, that stdin would be fed a file redirected from the > command line and then revert to a terminal device once there's no more > input from the redirected file. > > The problem is now how do I achieve that behaviour? When the program > starts, check if there's been a file redirected from the command line, > if so read that file storing relevant data, then -either way- make sure > I can read a character entered by the user from the terminal/keyboard to > give confirmation that proceeding is ok? > > I've got a much better understanding of stdin now, but for the life of > me can't work out how to do this. > > Thanks and regards, and apologies for my amateurishness. Ok sorry, it is in the faq: http://www.c-faq.com/stdio/devtty.html Is reading the file '/dev/tty' as keyboard input guaranteed on all Unix/Linux systems? Thanks again everyone. It's working. Pheww! :)
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: a.out and ELF file formats Next: Is there a C library function to open a file found in a path? |