473,379 Members | 1,491 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,379 software developers and data experts.

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 3445
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Andrew Kibler | last post by:
Two sections of code, in the first one fwrite works, in the second one it doesn't (ms VC++) both are identical except in the working one fseek is used twice to set the file pointer, once just...
13
by: William L. Bahn | last post by:
I'm sure this has been asked before, and I have looked in the FAQ, but I'm looking for an explanation for the following: The functions pairs: gets()/fgets() puts()/fputs() printf()/fprintf()...
8
by: Bill Cunningham | last post by:
Would getc and ungetc be the best and most simple what to parse expressions for a parser? Bill
19
by: mailursubbu | last post by:
HI, Below is my program. I compiled it through g++. Now strange thing is, getc is not reading the data instead its printing the previously read data ! Please some one let me know whats wrong. ...
62
by: Argento | last post by:
I was curious at the start about how ungetc() returns the character to the stream, so i did the following coding. Things work as expected except if I change the scanf("%c",&j) to scanf("%d",&j). I...
7
by: hzmonte | last post by:
My C program has the following: static int skip_space(FILE *fp, int *line, int c) { int i = 0; if(feof(fp)) { printf("in skip feof ...\n"); } printf("in skip start fp=%p line=%d c=%d\n", fp,...
15
by: av | last post by:
Why is so danger to allow ungetc(EOF, pfile); (for close the imput stream) ?
5
by: Richard Weeks | last post by:
Below is a fragment from a program that calculates statistics on x,y data. I want the user to be able to predict one or more predicted values of y from x, given the line of best fit. I have a...
32
by: vippstar | last post by:
Assuming all the values of int are in the range of unsigned char, what happends if getc returns EOF? Is it possible that EOF was the value of the byte read? Does that mean that code aiming for...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.