469,946 Members | 1,390 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,946 developers. It's quick & easy.

getc can return EOF, but ungetc can't sent it back... why?

Hello C programmers,

Can someone tell me why ungetc can't sent back EOF, but it's sister
function getc has no trouble sending it to us? For a file, this might
not make a difference, but for an interactive terminal, it is probably
nice to push EOF back (because to user doesn't want to provide an EOF
twice).

How is it getc can send EOF down it's pipe, but we can't send EOF down
ungetc's pipe (especially when this pipe is the same)? ungetc takes an
int as it's argument, so there shouldn't be any conflict between EOF
and any valid character, so what is the reason?

I realize this might be a basic question, but unfortunately I'm
confused and can't find the answer anywhere.

Nov 14 '05 #1
11 3217
j

"TTroy" <ti*****@gmail.com> wrote in message
news:11**********************@l41g2000cwc.googlegr oups.com...
Hello C programmers,

Can someone tell me why ungetc can't sent back EOF, but it's sister
function getc has no trouble sending it to us? For a file, this might
not make a difference, but for an interactive terminal, it is probably
nice to push EOF back (because to user doesn't want to provide an EOF
twice).

How is it getc can send EOF down it's pipe, but we can't send EOF down
ungetc's pipe (especially when this pipe is the same)? ungetc takes an
int as it's argument, so there shouldn't be any conflict between EOF
and any valid character, so what is the reason?

I realize this might be a basic question, but unfortunately I'm
confused and can't find the answer anywhere.


EOF is returned based on a condition and not based on some value
read in from the stream. (except there is a discrepancy when
sizeof(unsigned char) == sizeof(int))
As such, it would be nonsensical for ungetc to push EOF back into
the stream.

--
j
Nov 14 '05 #2
TTroy wrote:

Can someone tell me why ungetc can't sent back EOF, but it's sister
function getc has no trouble sending it to us? For a file, this might
not make a difference, but for an interactive terminal, it is probably
nice to push EOF back (because to user doesn't want to provide an EOF
twice).

How is it getc can send EOF down it's pipe, but we can't send EOF down
ungetc's pipe (especially when this pipe is the same)? ungetc takes an
int as it's argument, so there shouldn't be any conflict between EOF
and any valid character, so what is the reason?

I realize this might be a basic question, but unfortunately I'm
confused and can't find the answer anywhere.


[1] c:\c\junk>cat junk.c
#include <stdio.h>

int main(void)
{
int ch;

while (EOF != (ch = getc(stdin))) continue;
if (EOF == getc(stdin)) puts("Still at EOF");
else puts("EOF was transient");
ungetc(ch, stdin);
puts("Tried to put back EOF");
if (EOF == getc(stdin)) puts("Still at EOF");
else puts("EOF was transient");
return 0;
}

For what it's worth:

[1] c:\c\junk>cat junk.c
#include <stdio.h>

int main()
{
int ch;

while (EOF != (ch = getc(stdin))) continue;
if (EOF == getc(stdin)) puts("Still at EOF");
else puts("EOF was transient");
ungetc(ch, stdin);
puts("Tried to put back EOF");
if (EOF == getc(stdin)) puts("Still at EOF");
else puts("EOF was transient");
ungetc('a', stdin);
puts("Tried to put back 'a'");
if (EOF == getc(stdin)) puts("Still at EOF");
else puts("EOF was transient");
return 0;
}

[1] c:\c\junk>gcc junk.c -o junk

[1] c:\c\junk>junk
blah blah blah
^Z
Still at EOF
Tried to put back EOF
Still at EOF
Tried to put back 'a'
EOF was transient

[1] c:\c\junk>junk <junk.c
Still at EOF
Tried to put back EOF
Still at EOF
Tried to put back 'a'
EOF was transient

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #3


TTroy wrote:
Hello C programmers,

Can someone tell me why ungetc can't sent back EOF, but it's sister
function getc has no trouble sending it to us? For a file, this might
not make a difference, but for an interactive terminal, it is probably
nice to push EOF back (because to user doesn't want to provide an EOF
twice).

How is it getc can send EOF down it's pipe, but we can't send EOF down
ungetc's pipe (especially when this pipe is the same)? ungetc takes an
int as it's argument, so there shouldn't be any conflict between EOF
and any valid character, so what is the reason?

I realize this might be a basic question, but unfortunately I'm
confused and can't find the answer anywhere.


ungetc() is often used to provide a look-ahead: you
read a character with getc(), inspect it and decide you
really didn't want to read it yet, and push it back with
ungetc(). However, ungetc() is also capable of pushing
back a different character than the one getc() read; that's
why it takes two arguments instead of just one. The latter
use is perhaps unusual, but one can imagine using a sequence
of getc() calls to read in "&lt;", say, and then using
ungetc('<', fp) to "push back" its translation.

With this in mind, suppose your user types forty-two
characters and hits RETURN, and you start reading them in
with getc(). For some odd reason, you call ungetc(EOF, fp)
after reading ten characters. Now: what should the next
getc() return? If it returns EOF, it's saying there's no
more input -- but in fact, there is. If it returns something
other than EOF, what was the point of the ungetc() call? (A
fanciful thought: maybe ungetc(EOF, stdin) could be the oft-
sought fflush(stdin) ... ;-)

The value EOF is not an exceptional condition, it is a
report of an exceptional condition. The reading on your
thermometer is not the temperature, it is a report of the
temperature. You cannot melt the snowbanks by changing the
markings on your thermometer, and you cannot influence the
actual I/O condition by manipulating the EOF value that
reports it.

--
Er*********@sun.com

Nov 14 '05 #4
On Wed, 09 Mar 2005 13:01:12 -0800, TTroy wrote:
Hello C programmers,

Can someone tell me why ungetc can't sent back EOF, but it's sister
function getc has no trouble sending it to us?
EOF is not a characer value, it is a failure indicator. When getc()
returns EOF it is saying "I couldn't get a character for you". The reason
for that might be that the stream is at end-of-file (which you can detect
with feof()) or maybe some error occurred on the strean (which you can
detect with ferror()).
For a file, this might
not make a difference, but for an interactive terminal, it is probably
nice to push EOF back (because to user doesn't want to provide an EOF
twice).
Since EOF isn't a character it makes little sense to "push it back".
If you pass the value of EOF to ungetc() it fails and does nothing to the
stream. So if the stream was at end-of-file it will still be after such an
ungetc() call, and if the stream has an error condition flagged it will
still do so after such a call. I'm not sure how this differs from what you
are requesting.
How is it getc can send EOF down it's pipe, but we can't send EOF down
ungetc's pipe (especially when this pipe is the same)?
Because EOF isn't a character in the pipe, it is information about the
pipe's state.
ungetc takes an
int as it's argument, so there shouldn't be any conflict between EOF
and any valid character, so what is the reason?


That's not a problem, ungetc() has a specified behaviour for an EOF
argument.

Lawrence
Nov 14 '05 #5
Lawrence Kirby wrote:
On Wed, 09 Mar 2005 13:01:12 -0800, TTroy wrote:
Hello C programmers,

Can someone tell me why ungetc can't sent back EOF, but it's sister
function getc has no trouble sending it to us?
EOF is not a characer value, it is a failure indicator. When getc()
returns EOF it is saying "I couldn't get a character for you". The

reason for that might be that the stream is at end-of-file (which you can detect with feof()) or maybe some error occurred on the strean (which you can detect with ferror()).
For a file, this might
not make a difference, but for an interactive terminal, it is probably nice to push EOF back (because to user doesn't want to provide an EOF twice).
Since EOF isn't a character it makes little sense to "push it back".
If you pass the value of EOF to ungetc() it fails and does nothing to

the stream. So if the stream was at end-of-file it will still be after such an ungetc() call, and if the stream has an error condition flagged it will still do so after such a call. I'm not sure how this differs from what you are requesting.


My question is the use of EOF specifically as an EXIT flag in programs
coming from user input from keyboard. Thus a user provides EOF to
signal that the program should be ended. Unlike EOF for end of file
indication, this user provided EOF is momentary, and will be missed if
the part of the program that reacts to EOF doesn't read it (so another
part reads it). I just wanted a way where the -other part- could push
back anything even EOF so the part that runs the whole show will see
the EOF and end the program.

I realize the valid points you guys have made and now I'm satisified
knowing that what I wanted really isn't possible (I hate thinking -
there must be a way to do this but I can't figure it out- but now I'm
thinking - this is impossible so shut up brain!!!-).

thanks,
Tinesan Troy, B.Eng (Mech)
ti*****@gmail.com

Nov 14 '05 #6
TTroy <ti*****@gmail.com> wrote:

My question is the use of EOF specifically as an EXIT flag in programs
coming from user input from keyboard. Thus a user provides EOF to
signal that the program should be ended. Unlike EOF for end of file
indication, this user provided EOF is momentary, and will be missed if
the part of the program that reacts to EOF doesn't read it (so another
part reads it).


That is not correct -- once a stream (even one connected to a keyboard)
reaches EOF, the EOF indicator for that stream is set and all subsequent
I/O operations also return EOF until the program explicitly resets the
EOF indicator. If your implementation doesn't behave that way, it's not
conforming.

-Larry Jones

I can feel my brain beginning to atrophy already. -- Calvin
Nov 14 '05 #7
la************@ugs.com wrote:
TTroy <ti*****@gmail.com> wrote:

My question is the use of EOF specifically as an EXIT flag in programs
coming from user input from keyboard. Thus a user provides EOF to
signal that the program should be ended. Unlike EOF for end of file
indication, this user provided EOF is momentary, and will be missed if
the part of the program that reacts to EOF doesn't read it (so another
part reads it).


That is not correct -- once a stream (even one connected to a keyboard)
reaches EOF, the EOF indicator for that stream is set and all subsequent
I/O operations also return EOF until the program explicitly resets the
EOF indicator. If your implementation doesn't behave that way, it's not
conforming.


However the input driver may well insist that that EOF signal be at
the very beginning of a line. Thus:

<blah blah><CTL-Z><ENTER>

is not seen as EOF. However

<blah blah><ENTER><CTL-Z><ENTER>

is an EOF signal, after the blah blah line. Under Unix use CTL-D.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #8
la************@ugs.com writes:
TTroy <ti*****@gmail.com> wrote:

My question is the use of EOF specifically as an EXIT flag in programs
coming from user input from keyboard. Thus a user provides EOF to
signal that the program should be ended. Unlike EOF for end of file
indication, this user provided EOF is momentary, and will be missed if
the part of the program that reacts to EOF doesn't read it (so another
part reads it).


That is not correct -- once a stream (even one connected to a keyboard)
reaches EOF, the EOF indicator for that stream is set and all subsequent
I/O operations also return EOF until the program explicitly resets the
EOF indicator. If your implementation doesn't behave that way, it's not
conforming.


It's worth noting that a lot of real-world implementations allow
characters to be read from an interactive stream after EOF. (I think
there's been some dispute as to whether this behavior really is
non-conforming, but it is common.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #9
Keith Thompson wrote:
la************@ugs.com writes:
TTroy <ti*****@gmail.com> wrote:

My question is the use of EOF specifically as an EXIT flag in
programs coming from user input from keyboard. Thus a user
provides EOF to signal that the program should be ended. Unlike
EOF for end of file indication, this user provided EOF is
momentary, and will be missed if the part of the program that
reacts to EOF doesn't read it (so another part reads it).


That is not correct -- once a stream (even one connected to a
keyboard) reaches EOF, the EOF indicator for that stream is set
and all subsequent I/O operations also return EOF until the
program explicitly resets the EOF indicator. If your
implementation doesn't behave that way, it's not conforming.


It's worth noting that a lot of real-world implementations allow
characters to be read from an interactive stream after EOF. (I
think there's been some dispute as to whether this behavior
really is non-conforming, but it is common.)


That depends on where in the system the EOF is made sticky. I
remember on the HP3000, once you sent an EOF signal from a
terminal, that terminal was down until either the system was
warmbooted or special operator action was taken to release the
terminal. The signal was ":EOF" at the left of a line, without the
quotes. Useful for annoying your cow-orkers.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #10
Eric Sosman wrote:

<snip>
The value EOF is not an exceptional condition, it is a
report of an exceptional condition. The reading on your
thermometer is not the temperature, it is a report of the
temperature. You cannot melt the snowbanks by changing the
markings on your thermometer, and you cannot influence the
actual I/O condition by manipulating the EOF value that
reports it.


Well put-- that's a very apt analogy. I'll have to save this one.
Mark F. Haigh
mf*****@sbcglobal.net

Nov 14 '05 #11
In article <42***************@yahoo.com> cb********@worldnet.att.net writes:
....
However the input driver may well insist that that EOF signal be at
the very beginning of a line. Thus:
<blah blah><CTL-Z><ENTER>
is not seen as EOF. However
<blah blah><ENTER><CTL-Z><ENTER>
is an EOF signal, after the blah blah line. Under Unix use CTL-D.


Or (under Unix) enter CTL-D twice when you want EOF in the middle of
a line.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Andrew Kibler | last post: by
13 posts views Thread by William L. Bahn | last post: by
8 posts views Thread by Bill Cunningham | last post: by
19 posts views Thread by mailursubbu | last post: by
62 posts views Thread by Argento | last post: by
7 posts views Thread by hzmonte | last post: by
15 posts views Thread by av | last post: by
5 posts views Thread by Richard Weeks | last post: by
32 posts views Thread by vippstar | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.