From: Poster Matt on 1 Mar 2010 09:52 Ben Bacarisse wrote: > Poster Matt <postermatt(a)no_spam_for_me.org> writes: > >> 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. Yes, I had got that. What I should have said is that on my system when printing EOF cast as a char, 'ÿ' is displayed. Cheers.
From: Eric Sosman on 1 Mar 2010 11:15 On 3/1/2010 9:16 AM, Poster Matt wrote: > [... getchar() for user input when stdin comes from a 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. The important point is that stdin is *one* stream, reading from *one* source of data. If you've got two different data sources -- a file plus a keyboard (or whatever), you can't use the same stream for both of them. Well, actually, you can -- but not at the same time, or in the same "incarnation." There's freopen(), which allows you to reassign stdin (or another stream) at will, so you could use stdin to read your file, then reassign it and re-use it to read from /dev/tty. Or you could open an independent stream on /dev/tty and read from that. This is, however, quite often a Bad Idea: It means your program cannot be used non-interactively, as in `echo y | program' or even `yes | program' -- and the inability to do such things raises barriers to use by scripts or in daemons and so on. I think you need to take a step backward and ponder why you need interactive confirmation. Is your program about to start a potentially dangerous or expensive operation? If not, you might be better off just letting it run. Or you might skip the confirmation step if you can tell you're running non-interactively (isatty() is a reasonable starting point, but "The device is some kind of tty" is not exactly the same thing as "A user is watching over me"). Solidify your requirements; decide what you really need/want to do. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Poster Matt on 1 Mar 2010 11:49 Eric Sosman wrote: > On 3/1/2010 9:16 AM, Poster Matt wrote: >> [... getchar() for user input when stdin comes from a 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. > > The important point is that stdin is *one* stream, reading > from *one* source of data. If you've got two different data > sources -- a file plus a keyboard (or whatever), you can't use > the same stream for both of them. > > Well, actually, you can -- but not at the same time, or in > the same "incarnation." There's freopen(), which allows you to > reassign stdin (or another stream) at will, so you could use > stdin to read your file, then reassign it and re-use it to read > from /dev/tty. Or you could open an independent stream on > /dev/tty and read from that. This is, however, quite often a > Bad Idea: It means your program cannot be used non-interactively, > as in `echo y | program' or even `yes | program' -- and the > inability to do such things raises barriers to use by scripts > or in daemons and so on. > > I think you need to take a step backward and ponder why you > need interactive confirmation. Is your program about to start > a potentially dangerous or expensive operation? If not, you > might be better off just letting it run. Or you might skip the > confirmation step if you can tell you're running non-interactively > (isatty() is a reasonable starting point, but "The device is some > kind of tty" is not exactly the same thing as "A user is watching > over me"). Solidify your requirements; decide what you really > need/want to do. Thanks for the further explanation, appreciated. I require user confirmation for two reasons. Firstly the command line switches are extensive, 25 at the moment, so easy for a user to omit one by accident. So the program outputs a message stating exactly what will take place. Secondly the operations performed are potentially time consuming, possibly as much as 15-20 minutes on my system. So the user will waste time if the command line is wrong, or be forced to use a dirty exit. For script use or for a seasoned user, there's already a 'bypass confirmation' switch. Here's what I'm now doing to be able to (possibly) read a file from stdin that's been redirected on the command line, and to get user confirmation: if (isatty(fileno(stdin)) == 0) stdin is not a terminal device - search stdin for the expected data. then later when getting the user confirmation: int c; // stdin is a terminal device, read a character from stdin. if (isatty(fileno(stdin)) == 1) c = getchar(); // stdin is not a terminal device, open '/dev/tty'. else { FILE* fp = fopen("/dev/tty", "r"); if (fp == NULL) { strcpy(errMsg, ErrOpeningDevTty); return false; } c = fgetc(fp); fclose(fp); } How does that look? By the way is reading '/dev/tty' as keyboard input guaranteed on all Unix/Linux systems? Many thanks again, regards, Matt
From: Eric Sosman on 1 Mar 2010 13:44 On 3/1/2010 11:49 AM, Poster Matt wrote: > [...] > By the way is reading '/dev/tty' as keyboard input guaranteed on all > Unix/Linux systems? Yes, sort of. /dev/tty is (an alias for) the process' "controlling terminal." That device might be a tty with a keyboard, or a pty, or a serial line with unknown gadgetry at the far end, or ... It's Unix' notion of a device that someone/something can use to "control" the process. However, a process might have no "controlling terminal" at all; this is quite commonly the case for daemons, and can also be true for other processes. So in that sense, No: the existence of /dev/tty is not guaranteed. (Off-hand, I don't recall whether an attempt to open /dev/tty when there's no controlling terminal simply fails, or opens /dev/null instead; look it up for yourself.) In any event, there do exist Unix processes that are not associated with any interactive devices at all -- which would make "user confirmation" difficult ... -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Barry Margolin on 1 Mar 2010 16:07 In article <d%Pin.46118$Ym4.7352(a)text.news.virginmedia.com>, Poster Matt <postermatt(a)no_spam_for_me.org> wrote: > 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? If you want stdin to revert to its previous value when the end of the file is reached, you can invoke your program as follows: cat filename - | program Supplying a filename of "-" to cat refers to cat's stdin. However, if your program reads to EOF, and then expects to read the answer to a question from the user, the above won't work, because your program won't see EOF when the end of the file is reached. -- Barry Margolin, barmar(a)alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
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? |