Question about the getchar() and eof !!!...

N

neras

Hi..
I can't well english..i'm korean;...

At first,, You see the my source.

-----------------------------------------------
int main(void)
{
long nc=0;
while( getchar()!=EOF )
++nc;
printf("%ld\n",nc);
return 0;
}
--------------------------------------------------------
It is very short.
I thinking the result but my thinking not like compiler;

123ctrl+z123enter
I Thinking the print 3 and program is exit.
But program is not exit;

and I add the 3 line the at like bottm
123ctrl+z123enter
123ctrl+z123enter
123ctrl+z1231enter
ctrl+zenter

It Was Succed the program exit;
Result is 12.

Why don't the program was exit at first line ???
Why result is 12????
Is EOF at first in line???

Thx.
 
A

A. Sinan Unur

-----------------------------------------------
int main(void)
{
long nc=0;
while( getchar()!=EOF )
++nc;
printf("%ld\n",nc);
return 0;
}

This has nothing to do with the compiler.
123ctrl+z123enter
I Thinking the print 3 and program is exit.
But program is not exit;

and I add the 3 line the at like bottm
123ctrl+z123enter
123ctrl+z123enter
123ctrl+z1231enter
ctrl+zenter

It Was Succed the program exit;
Result is 12.

Why don't the program was exit at first line ???

Because that is just the way it works on Windows: You need to enter
CTRL-Z all by itself on a line to signal end of console input.

Sinan
 
S

Suman

neras said:
Hi..
I can't well english..i'm korean;... Welcome!

At first,, You see the my source.

-----------------------------------------------
int main(void)
{
long nc=0;
while( getchar()!=EOF )

My compiler (gcc version 3.3.3) doesn't like this line and has enough
to crib:
[1] warning: implicit declaration of function `getchar'
which means, you need a prototype in scope for
getchar()
[2] error: `EOF' undeclared (first use in this function)
and that, it has no idea what EOF is.
So, to fix them, do a #include <stdio.h> anywhere before you use
EOF/getchar()/
printf() where it will:
a. find a prototype: int getchar(void)
b. and come to know that EOF is a macro: # define EOF (-1) /* or
somesuch value */
++nc;
printf("%ld\n",nc);

And so for printf()...
return 0;
}
-------------------------------------------------------- [ ... ]

Why don't the program was exit at first line ???

You need to be very sure about which key combination would be
equivalent to
EOF for your system. So...
Why result is 12????

What were you expecting?
Is EOF at first in line???

Which line?
 
V

Vladimir S. Oka

neras said:
Hi..
I can't well english..i'm korean;...

At first,, You see the my source.

-----------------------------------------------

You need to:

#include <stdio.h>

Otherwise, `printf`, `getchar`, and `EOF` are unknown. I'd be surprised
if you were able to compile without it (for lack of `EOF` mostly).
int main(void)
{
long nc=0;
while( getchar()!=EOF )
++nc;
printf("%ld\n",nc);
return 0;
}
--------------------------------------------------------
It is very short.
I thinking the result but my thinking not like compiler;

123ctrl+z123enter
I Thinking the print 3 and program is exit.
But program is not exit;

and I add the 3 line the at like bottm
123ctrl+z123enter
123ctrl+z123enter
123ctrl+z1231enter
ctrl+zenter

It Was Succed the program exit;
Result is 12.

Why don't the program was exit at first line ???
Why result is 12????
Is EOF at first in line???

Works same for me, and I think it does what it should, and your program
is correct (apart from missing #include). It just seems that you need
Ctrl-Z on a line of it's own to force EOF condition. That is to do
with your particular C implementation.
 
R

ranjmis

neras said:
Hi..
I can't well english..i'm korean;...

At first,, You see the my source.

-----------------------------------------------
int main(void)
{
long nc=0;
while( getchar()!=EOF )
++nc;
printf("%ld\n",nc);
return 0;
}
--------------------------------------------------------

Let me modify the program to print the value given by getchar
Also include stdio.h
--------------------------
#include<stdio.h>
int main(void)
{
long nc=0;
int val=0;
while( (val=getchar())!=12 ) {
printf(" %d ",val);
++nc;
}
printf("%ld\n",nc);
return 0;
}

---------------------------
It is very short.
I thinking the result but my thinking not like compiler;

123ctrl+z123enter
123^Z123
49 50 51

so it stops at ^Z
I Thinking the print 3 and program is exit.
But program is not exit;

and I add the 3 line the at like bottm
123ctrl+z123enter
123ctrl+z123enter
123ctrl+z1231enter
ctrl+zenter

If I give above input it gives

123^Z123
49 50 51 123^Z123
49 50 51 123^Z1231
49 50 51 ^Z
-1

So If you give only "^zenter" in one line the value is -1 otherwise it
just stops scanning at ^z.
It Was Succed the program exit;
Result is 12.

Result should be 9 instead
 
V

Vladimir S. Oka

ranjmis said:
Let me modify the program to print the value given by getchar
Also include stdio.h
--------------------------
#include<stdio.h>
int main(void)
{
long nc=0;
int val=0;
while( (val=getchar())!=12 ) {

This is not the same as `== EOF` test, and most likely still not what
the OP wanted in the first place. You are not correcting it, you are
breaking it.
printf(" %d ",val);
++nc;
}
printf("%ld\n",nc);
return 0;
}

said:
Result should be 9 instead

Again, you are wrong, and OP was right. The problem was in Windows
wanting a Ctrl-Z on a line of its own in order to trigger EOF
condition.

Please stop posting bad advice (this is your second today).
 
P

Pedro Graca

neras said:
Is EOF at first in line???

EOF is *not* a character.

When getchar() returns a character, that character will be an
(implementation defined) unsigned char converted to int (probably
something with a value between 0 and 255). When getchar() returns EOF
that means getchar() didn't get a character but instead found out the
input has ended.
 
R

Richard Tobin

Pedro Graca said:
EOF is *not* a character.

The C macro EOF is not a character. Unfortunately when discussing
end-of-file on terminal devices, you often - depending on the
operating system - have to mention a character typed at the keyboard,
which is often also referred to as EOF.

-- Richard
 
K

Keith Thompson

The C macro EOF is not a character. Unfortunately when discussing
end-of-file on terminal devices, you often - depending on the
operating system - have to mention a character typed at the keyboard,
which is often also referred to as EOF.

I certainly hope it isn't referred to as EOF.

At least in the context of this newsgroup, EOF has one clear meaning:
the macro defined in <stdio.h> which expands to the negative value
returned by getchar() on an end-of-file or error condition.

(There is no ASCII control character called "EOF".)
 
K

Keith Thompson

neras said:
At first,, You see the my source.
-----------------------------------------------
int main(void)
{
long nc=0;
while( getchar()!=EOF )
++nc;
printf("%ld\n",nc);
return 0;
}
[...]

Yes, a bit *too* short.

Others have already pointed out that you need a "#include <stdio.h>".
Without it, your program won't compile, which means that the code you
posted isn't the same as the code you actually compiled.

If you post code here, always post the *exact* code that you actually
compiled. Don't re-type it; copy-and-paste it. We know there's at
least one missing line in what you posted. There's no way we can
guess what else might be missing, which makes it difficult to help
you.
 
R

Richard Tobin

The C macro EOF is not a character. Unfortunately when discussing
end-of-file on terminal devices, you often - depending on the
operating system - have to mention a character typed at the keyboard,
which is often also referred to as EOF.
[/QUOTE]
I certainly hope it isn't referred to as EOF.

I fear you may be disappointed...

For example, the relevant manual page on the computer I am using
refers to the "EOF character" (which can be set to any character
of the user's choice).
At least in the context of this newsgroup, EOF has one clear meaning:

But the people asking questions don't know that. Therir problem is
precisely that they don't understand the relation and distinction
between C's EOF and what they type, so anyone saying

needs to explain it.
(There is no ASCII control character called "EOF".)

No, but many operating systems refer to an EOF character, meaning
the character typed to signal end-of-file.

-- Richard
 
P

Pedro Graca

Richard said:
so anyone saying


needs to explain it.

Didn't I explain it when I said that?
but many operating systems refer to an EOF character, meaning
the character typed to signal end-of-file.

Windows is stupid (... or I'm doing something terribly wrong)
It seems there is, in fact, an EOF character in Windows.

==== producer.c ====
#include <stdio.h>
#include <limits.h>

int main(void) {
int i;
for (i = 0; i <= UCHAR_MAX; ++i) {
putchar(i);
if (i % 32 == 15) putchar(EOF);
if (i % 32 == 31) putchar('\n');
}
return 0;
}


==== consumer.c ====
#include <stdio.h>

int main(void) {
long nc = 0;
int ch;

printf("EOF is %d\n\n", EOF);

while ((ch = getchar()) != EOF) {
printf("%d ", ch);
++nc;
}

printf("\n\ncounted %ld characters.\n", nc);
return 0;
}


Running "producer | consumer" we learn that the Linux version wrote and
read 272 charcaters while the Windows version wrote and read 26.

PS. I compiled with "gcc -W -Wall -std=c89 -pedantic -O2" on both
platforms;
Linux gcc is version 3.3.5; Windows 2000 gcc is version 3.3.3

Will try the same thing tomorrow (at work) with the Microsoft compiler
for Windows XP.
 
M

Mark McIntyre

Windows is stupid (... or I'm doing something terribly wrong)
It seems there is, in fact, an EOF character in Windows.

EOF is a macro. It may well have an integer value, so you may well be
able to print it. How DOS or Windows interprets it is another matter.

DOS and dos-based osen (including some *nix derivants) are well known
for considering ascii 26 to represent the end of a text file, and a
DOS or Windows compiler might emit ascii 26 when handed (int) EOF.
Similarly the system process reading a text file will consider ascii
26 to mark the end of the file, and consequently signal EOF to the
standard C library. This doesn't mean that ascii 26 /IS/ an EOF.
Running "producer | consumer" we learn that the Linux version wrote and
read 272 charcaters while the Windows version wrote and read 26.

What you probably learned is that stdin is a text stream, and the OS
you're using considers ascii 26 to be a marker for end-of-file in text
mode.
Mark McIntyre
 
K

Keith Thompson

But the people asking questions don't know that. Therir problem is
precisely that they don't understand the relation and distinction
between C's EOF and what they type, so anyone saying


needs to explain it.

Agreed. I thought it was explained.
 
M

Micah Cowan

Mark McIntyre said:
EOF is a macro. It may well have an integer value, so you may well be
able to print it. How DOS or Windows interprets it is another
matter.

???

It /must/ have an integer value. A negative one. Of type int. See 7.19.1#3.
 
R

Richard Tobin

needs to explain it.

Agreed. I thought it was explained.[/QUOTE]

My reason for complaining about the article I replied to was that it
only gave one half of the story: what EOF is in C. To correct
someone's misunderstanding about this you typically need to explicitly
contrast it with the operating system notion of end-of-file character,
since that's what they're confusing it with. Some of the other articles
did this.

-- Richard
 
P

Pedro Graca

Mark said:
EOF is a macro. It may well have an integer value, so you may well be
able to print it. How DOS or Windows interprets it is another matter.

Well ... putchar() accepts an int and then converts it to unsigned char
before printing, right?
So, all these lines

putchar(1024+65);
putchar(10240+65);
putchar(-1024+65);

will print a character with code 65 (ascii 'A'), right?
DOS and dos-based osen (including some *nix derivants) are well known
for considering ascii 26 to represent the end of a text file, and a
DOS or Windows compiler might emit ascii 26 when handed (int) EOF.

Not in my case.
putchar(EOF); /* outputs character with code 255 */
Similarly the system process reading a text file will consider ascii
26 to mark the end of the file, and consequently signal EOF to the
standard C library. This doesn't mean that ascii 26 /IS/ an EOF.

Ah! A further test indicates you're right.

while ((ch = getchar()) != EOF) {
/* void */
}
printf("Character code that stopped the while: %d\n", ch);

This will stop at the character with code 26, but report code -1.
What you probably learned is that stdin is a text stream, and the OS
you're using considers ascii 26 to be a marker for end-of-file in text
mode.

<ot Windows text files>
Oh, ok. I changed my `producer' to write to a binary file and `consumer'
to read from the same file and the "EOF character" was gone.


So ... Windows converts '\n' to "\r\n" for output to text files
and the other way around for input from text files;

*and*

it converts '\x1A' to an EOF condition for input, discarding that
particular character and all the following ones (and yet it allows one
to output as many '\x1A's as one wants to ...)

.... Stupid Windows
</ot>
 
J

Jordan Abel

Well ... putchar() accepts an int and then converts it to unsigned char
before printing, right?
So, all these lines

putchar(1024+65);
putchar(10240+65);
putchar(-1024+65);

will print a character with code 65 (ascii 'A'), right?

Wrong.
 
K

Keith Thompson

Pedro Graca said:
Well ... putchar() accepts an int and then converts it to unsigned char
before printing, right?
So, all these lines

putchar(1024+65);
putchar(10240+65);
putchar(-1024+65);

will print a character with code 65 (ascii 'A'), right?

Assuming that UCHAR_MAX < 1024, and assuming an ASCII character set:
yes. (It may require some additional assumptions about CHAR_MAX; I'm
too lazy to track down the details). I'm not sure what your point is.
Not in my case.
putchar(EOF); /* outputs character with code 255 */

If EOF==-1 (which is very common, if not effectively universal), and
UCHAR_MAX==255, then putchar(EOF) is equivalent to putchar(255).

What that causes to be written to the file is system-specific. It's
possible (but unlikely) that writing that particular value to a text
file will cause and end-of-file condition at that point when the file
is read (as the value 26 does under Windows). And mapping '\n' to the
system-specific end-of-line representation isn't necessarily the only
tranformation that's done when writing to a text file. C99 7.19.2p2:

A text stream is an ordered sequence of characters
composed into _lines_, each line consisting of zero or more
characters plus a terminating new-line character. Whether
the last line requires a terminating new-line character
is implementation-defined. Characters may have to be
added, altered, or deleted on input and output to conform
to differing conventions for representing text in the
host environment. Thus, there need not be a oneto- one
correspondence between the characters in a stream and those in
the external representation. Data read in from a text stream
will necessarily compare equal to the data that were earlier
written out to that stream only if: the data consist only of
printing characters and the control characters horizontal tab
and new-line; no new-line character is immediately preceded
by space characters; and the last character is a new-line
character. Whether space characters that are written out
immediately before a new-line character appear when read in
is implementation-defined.

So if you write a control character (other than horizontal tab and
new-line) to a text file, all bets are off.
 
K

Keith Thompson

Jordan Abel said:

How so? If you're referring to the assumption of an ASCII character
set, that makes it non-portable, not completely wrong. (For that
matter, code 65 is ascii 'A', even if some particular implementation
doesn't use ASCII -- though that's admittedly a bit of a stretch.)

If UCHAR_MAX is very large, the conversion to unsigned char may not
yield 65.

Apart from that, it seems ok.

Perhaps you'd care to expand on that a bit?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top