Is EOF always negative? - c

Is EOF always negative?
I'm thinking of writing a function that reads the next word in the input and returns the line number the word was found in or EOF if the end of the input has been reached. If EOF is not necessarily negative, the function would be incorrect.

EOF is always == EOF. Don't assume anything else.
On a second reading of the standard (and as per some other comments here) it seems EOF is always negative - and for the use specified in this question (line number or EOF) it would work. What I meant to warn against (and still do) is assuming characters are positive and EOF is negative.
Remember that it's possible for a standard conforming C implementation to have negative character values - this is even mentioned in 'The C programming language' (K&R). Printing characters are always positive, but on some architectures (probably all ancient), control characters are negative. The C standard does not specify whether the char type is signed or unsigned, and the only character constant guaranteed to have the same value across platforms, is '\0'.

Yes, EOF is always negative.
The Standard says:
7.19 Input/output
7.19.1 Introduction
3 The macros are [...] EOF which
expands to an integer constant
expression, with type int and a
negative value, that is returned by
several functions to indicate
end-of-file, that is, no more input
from a stream;
Note that there's no problem with "plain" char being signed. The <stdio.h> functions which deal with chars, specifically cast the characters to unsigned char and then to int, so that all valid characters have a positive value. For example:
int fgetc(FILE *stream)
7.19.7.1
... the fgetc function obtains that character as an unsigned char converted to an int ...

Have that function return
the line number the word was found in
or -1 in case the end of the input has been reached
Problem solved, without a need for relying on any EOF values. The caller can easily test for greater-or-equal-to-zero for a successful call, and assume EOF/IO-error otherwise.

From the online draft n1256, 17.9.1.3:
EOF
which expands to an integer constant expression, with type int and a negative value,
that is returned by several functions to indicate end-of-file, that is, no more input
from a stream;
EOF is always negative, though it may not always be -1.
For issues like this, I prefer separating error conditions from data by returning an error code (SUCCESS, END_OF_FILE, READ_ERROR, etc.) as the function's return value, and then writing the data of interest to separate parameters, such as
int getNextWord (FILE *stream, char *buffer, size_t bufferSize, int *lineNumber)
{
if (!fgets(buffer, bufferSize, stream))
{
if (feof(stream)) return END_OF_FILE; else return READ_ERROR;
}
else
{
// figure out the line number
*lineNumber = ...;
}
return SUCCESS;
}

EOF is a condition, rather than a value. The exact value of this sentinel is implementation defined. In a lot of cases, it is a negative number.

From wikipedia :
The actual value of EOF is a
system-dependent negative number,
commonly -1, which is guaranteed to be
unequal to any valid character code.
But no references ...
From Secure Coding : Detect and handle input and output errors
EOF is negative but only when sizeof(int) > sizeof(char).

Related

How to replace a character in a file in C [duplicate]

int main()
{
FILE *ft;
char ch;
ft=fopen("abc.txt","r+");
if(ft==NULL)
{
printf("can not open target file\n");
exit(1);
}
while(1)
{
ch=fgetc(ft);
if(ch==EOF)
{
printf("done");
break;
}
if(ch=='i')
{
fputc('a',ft);
}
}
fclose(ft);
return 0;
}
As one can see that I want to edit abc.txt in such a way that i is replaced by a in it.
The program works fine but when I open abc.txt externally, it seemed to be unedited.
Any possible reason for that?
Why in this case the character after i is not replace by a, as the answers suggest?
Analysis
There are multiple problems:
fgetc() returns an int, not a char; it has to return every valid char value plus a separate value, EOF. As written, you can't reliably detect EOF. If char is an unsigned type, you'll never find EOF; if char is a signed type, you'll misidentify some valid character (often ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS) as EOF.
If you switch between input and output on a file opened for update mode, you must use a file positioning operation (fseek(), rewind(), nominally fsetpos()) between reading and writing; and you must use a positioning operation or fflush() between writing and reading.
It is a good idea to close what you open (now fixed in the code).
If your writes worked, you'd overwrite the character after the i with a.
Synthesis
These changes lead to:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *ft;
char const *name = "abc.txt";
int ch;
ft = fopen(name, "r+");
if (ft == NULL)
{
fprintf(stderr, "cannot open target file %s\n", name);
exit(1);
}
while ((ch = fgetc(ft)) != EOF)
{
if (ch == 'i')
{
fseek(ft, -1, SEEK_CUR);
fputc('a',ft);
fseek(ft, 0, SEEK_CUR);
}
}
fclose(ft);
return 0;
}
There is room for more error checking.
Exegesis
Input followed by output requires seeks
The fseek(ft, 0, SEEK_CUR); statement is required by the C standard.
ISO/IEC 9899:2011 §7.21.5.3 The fopen function
¶7 When a file is opened with update mode ('+' as the second or third character in the
above list of mode argument values), both input and output may be performed on the
associated stream. However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by output without an
intervening call to a file positioning function, unless the input operation encounters end-of-
file. Opening (or creating) a text file with update mode may instead open (or create) a
binary stream in some implementations.
(Emphasis added.)
fgetc() returns an int
Quotes from ISO/IEC 9899:2011, the current C standard.
§7.21 Input/output <stdio.h>
§7.21.1 Introduction
EOF which expands to an integer constant expression, with type int and a negative value, that
is returned by several functions to indicate end-of-file, that is, no more input from a
stream;
§7.21.7.1 The fgetc function
int fgetc(FILE *stream);
¶2 If the end-of-file indicator for the input stream pointed to by stream is not set and a
next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the
stream (if defined).
Returns
¶3 If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the
fgetc function returns the next character from the input stream pointed to by stream.
If a read error occurs, the error indicator for the stream is set and the fgetc function
returns EOF.289)
289) An end-of-file and a read error can be distinguished by use of the feof and ferror functions.
So, EOF is a negative integer (conventionally it is -1, but the standard does not require that). The fgetc() function either returns EOF or the value of the character as an unsigned char (in the range 0..UCHAR_MAX, usually 0..255).
§6.2.5 Types
¶3 An object declared as type char is large enough to store any member of the basic
execution character set. If a member of the basic execution character set is stored in a
char object, its value is guaranteed to be nonnegative. If any other character is stored in
a char object, the resulting value is implementation-defined but shall be within the range
of values that can be represented in that type.
¶5 An object declared as type signed char occupies the same amount of storage as a
‘‘plain’’ char object.
§6 For each of the signed integer types, there is a corresponding (but different) unsigned
integer type (designated with the keyword unsigned) that uses the same amount of
storage (including sign information) and has the same alignment requirements.
§15 The three types char, signed char, and unsigned char are collectively called
the character types. The implementation shall define char to have the same range,
representation, and behavior as either signed char or unsigned char.45)
45) CHAR_MIN, defined in <limits.h>, will have one of the values 0 or SCHAR_MIN, and this can be
used to distinguish the two options. Irrespective of the choice made, char is a separate type from the
other two and is not compatible with either.
This justifies my assertion that plain char can be a signed or an unsigned type.
Now consider:
char c = fgetc(fp);
if (c == EOF)
…
Suppose fgetc() returns EOF, and plain char is an unsigned (8-bit) type, and EOF is -1. The assignment puts the value 0xFF into c, which is a positive integer. When the comparison is made, c is promoted to an int (and hence to the value 255), and 255 is not negative, so the comparison fails.
Conversely, suppose that plain char is a signed (8-bit) type and the character set is ISO 8859-15. If fgetc() returns ÿ, the value assigned will be the bit pattern 0b11111111, which is the same as -1, so in the comparison, c will be converted to -1 and the comparison c == EOF will return true even though a valid character was read.
You can tweak the details, but the basic argument remains valid while sizeof(char) < sizeof(int). There are DSP chips where that doesn't apply; you have to rethink the rules. Even so, the basic point remains; fgetc() returns an int, not a char.
If your data is truly ASCII (7-bit data), then all characters are in the range 0..127 and you won't run into the misinterpretation of ÿ problem. However, if your char type is unsigned, you still have the 'cannot detect EOF' problem, so your program will run for a long time. If you need to consider portability, you will take this into account. These are the professional grade issues that you need to handle as a C programmer. You can kludge your way to programs that work on your system for your data relatively easily and without taking all these nuances into account. But your program won't work on other people's systems.
You are not changing the 'i' in abc.txt, you are changing the next character after 'i'. Try to put fseek(ft, -1, SEEK_CUR); before your fputc('a', ft);.
After you read a 'i' character, the file position indicator of ft will be the character after this 'i', and when you write a character by fputc(), this character will be write at the current file position, i.e. the character after 'i'. See fseek(3) for further details.
After reading 'i' you need to "step back" to write to the correct location.
if(ch=='i')
{
fseek(ft, -1, SEEK_CUR);
fputc('a',ft);
}

Why is EOF defined to be −1 when −1 cannot be represented in a char?

I'm learning the C programming on a raspberry pi, however I found that my program never catches the EOF successfully. I use char c=0; printf("%d",c-1); to test the char type, finding that the char type ranges from 0 to 255, as an unsigned short. but the EOF defined in stdio.h is (-1). So is the wrong cc package installed on my Pi? how can I fix it? If I changed the EOF value in stdio.h manually, will there be further problems?
what worries me is that ,when I learning from the K&R book, there are examples which use code like while ((c=getchar())!=EOF), I followed that on my Ubuntu machine and it works fine. I just wonder if such kind of syntax is abandoned by modern C practice or there is something conflict in my Raspberry Pi?
here is my code:
#include <stdio.h>
int main( void )
{
char c;
int i=0;
while ((c=getchar())!=EOF&&i<50) {
putchar(c);
i++;
}
if (c==EOF)
printf("\nEOF got.\n");
while ((c=getchar())!=EOF&&i<500) {
printf("%d",c);
i++;
}
}
even when I redirect the input to an file, it keeps printing 255 on the screen, never terminate this program.
Finally I found that I'm wrong,In the K&R book, it defined c as an int, not a char. Problem solved.
You need to store the character read by fgetc(), getchar(), etc. in an int so you can catch the EOF. This is well-known and has always been the case everywhere. EOF must be distinguishable from all proper characters, so it was decided that functions like fgetc() return valid characters as non-negative values (even if char is signed). An end-of-file condition is signalled by -1, which is negative and thus cannot collide with any valid character fgetc() could return.
Do not edit the system headers and especially do not change the value of constants defined there. If you do that, you break these headers. Notice that even if you change the value of EOF in the headers, this won't change the value functions like fgetc() return on end-of-file or error, it just makes EOF have the wrong value.
Why is EOF defined to be −1 when −1 cannot be represented in a char?
Because EOF isn't a character but a state.
If I changed the EOF value in stdio.h manually, will there be further
problems?
Absolutely, since you would be effectively breaking the header entirely. A header is not an actual function, just a set of prototypes and declarations for functions that are defined elsewhere ABSOLUTELY DO NOT change system headers, you will never succeed in doing anything but breaking your code, project and/or worse things.
On the subject of EOF: EOF is not a character, and thus cannot be represented in a character variable. To get around this, most programmers simple use an int value (by default signed) that can interpret the -1 from EOF. The reason that EOF can never be a character is because otherwise there would be one character indistinguishable from the end of file indicator.
int versus char.
fgetc() returns an int, not char. The values returned are in the range of unsigned char and EOF. This is typically 257 different values. So saving the result in char, signed char, unsigned char will lose some distinguishably.
Instead save the fgetc() return value in an int. After testing for an EOF result, the value can be saved as a char if needed.
// char c;
int c;
...
while ((c=getchar())!=EOF&&i<50) {
char ch = c;
...
Detail: "Why is EOF defined to be −1 when −1 cannot be represented in a char?" misleads. On systems where char is signed and EOF == -1, a char can have the value of EOF. Yet on such systems, a char can have a value of -1 that represents a character too - they overlap. So a char cannot distinctively represent all char and EOF. Best to use an int to save the return value of fgetc().
... the fgetc function obtains that character as an unsigned char converted to an int and ...
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, ... and the fgetc function returns EOF. ... C11 §7.21.7.1 2-3

*Might* an unsigned char be equal to EOF? [duplicate]

This question already has answers here:
Can sizeof(int) ever be 1 on a hosted implementation?
(8 answers)
Closed 7 years ago.
When using fgetc to read the next character of a stream, you usually check that the end-of-file was not attained by
if ((c = fgetc (stream)) != EOF)
where c is of int type. Then, either the end-of-file has been attained and the condition will fail, or c shall be an unsigned char converted to int, which is expected to be different from EOF —for EOF is ensured to be negative. Fine... apparently.
But there is a small problem... Usually the char type has no more than 8 bits, while int must have at least 16 bits, so every unsigned char will be representable as an int. Nevertheless, in the case char would have 16 or 32 bits (I know, this is never the case in practice...), there is no reason why one could not have sizeof(int) == 1, so that it would be (theoretically!) possible that fgetc (stream) returns EOF (or another negative value) but that end-of-file has not been attained...
Am I mistaken? Is it something in the C standard that prevents fgetc to return EOF if end-of-file has not been attained? (If yes, I could not find it!). Or is the if ((c = fgetc (stream)) != EOF) syntax not fully portable?...
EDIT: Indeed, this was a duplicate of Question #3860943. I did not find that question at first search. Thank for your help! :-)
You asked:
Is it something in the C standard that prevents fgetc to return EOF if end-of-file has not been attained?
On the contrary, the standard explicitly allows EOF to be returned when an error occurs.
If a read error occurs, the error indicator for the stream is set and the fgetc function returns EOF.
In the footnotes, I see:
An end-of-file and a read error can be distinguished by use of the feof and ferror functions.
You also asked:
Or is the if ((c = fgetc (stream)) != EOF) syntax not fully portable?
On the theoretical platform where CHAR_BIT is more than 8 and sizeof(int) == 1, that won't be a valid way to check that end-of-file has been reached. For that, you'll have to resort to feof and ferror.
c = fgetc (stream);
if ( !feof(stream) && !ferror(stream) )
{
// Got valid input in c.
}
I think you need to rely on stream error.
ch = fgetc(stream);
if (ferror(stream) && (ch == EOF)) /* end of file */;
From the standard
If a read error occurs, the error indicator for the stream is set and the fgetc function returns EOF.
Edit for better version
ch = fgetc(stream);
if (ch == EOF) {
if (ferror(stream)) /* error reading */;
else if (feof(stream)) /* end of file */;
else /* read valid character with value equal to EOF */;
}
If you are reading a stream that is standard ASCII only, there's no risk of receiving the char equivalent to EOF before the real end-of-file, because valid ASCII char codes go up to 127 only. But it could happen when reading a binary file. The byte would need to be 255(unsigned) to correspond to a -1 signed char, and nothing prevents it from appearing in a binary file.
But about your specific question (if there's something in the standard), not exactly... but notice that fgetc promotes the character as an unsigned char, so it won't ever be negative in this case anyway. The only risk would be if you had explicitly or implicitly cast down the return value to signed char (for instance, if your c variable were signed char).
NOTE: as #Ulfalizer mentioned in the comments, there's one rare case in which you may need to worry: if sizeof(int)==1, and you're reading a file that contains non-ascii characters, then you may get a -1 return value that is not the real EOF. Notice that environments in which this happens are quite rare (to my knowledge, compilers for low-end 8-bit microcontrollers, like the 8051). In such a case, the safe option would be to test feof() as #pmg suggested.
I agree with your reading.
C Standard says (C11, 7.21.7.1 The fgetc function p3):
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the endof-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the fgetc function returns the next character from the input stream pointed to by stream. If a read error occurs, the error indicator for the stream is set and the fgetc function
returns EOF.
There is nothing in the Standard (assuming UCHAR_MAX > INT_MAX) that disallows fgetc in a hosted implementation to return a value equal to EOF that is neither an end-of-file nor an error condition indicator.

modify existing contents of file in c

int main()
{
FILE *ft;
char ch;
ft=fopen("abc.txt","r+");
if(ft==NULL)
{
printf("can not open target file\n");
exit(1);
}
while(1)
{
ch=fgetc(ft);
if(ch==EOF)
{
printf("done");
break;
}
if(ch=='i')
{
fputc('a',ft);
}
}
fclose(ft);
return 0;
}
As one can see that I want to edit abc.txt in such a way that i is replaced by a in it.
The program works fine but when I open abc.txt externally, it seemed to be unedited.
Any possible reason for that?
Why in this case the character after i is not replace by a, as the answers suggest?
Analysis
There are multiple problems:
fgetc() returns an int, not a char; it has to return every valid char value plus a separate value, EOF. As written, you can't reliably detect EOF. If char is an unsigned type, you'll never find EOF; if char is a signed type, you'll misidentify some valid character (often ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS) as EOF.
If you switch between input and output on a file opened for update mode, you must use a file positioning operation (fseek(), rewind(), nominally fsetpos()) between reading and writing; and you must use a positioning operation or fflush() between writing and reading.
It is a good idea to close what you open (now fixed in the code).
If your writes worked, you'd overwrite the character after the i with a.
Synthesis
These changes lead to:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *ft;
char const *name = "abc.txt";
int ch;
ft = fopen(name, "r+");
if (ft == NULL)
{
fprintf(stderr, "cannot open target file %s\n", name);
exit(1);
}
while ((ch = fgetc(ft)) != EOF)
{
if (ch == 'i')
{
fseek(ft, -1, SEEK_CUR);
fputc('a',ft);
fseek(ft, 0, SEEK_CUR);
}
}
fclose(ft);
return 0;
}
There is room for more error checking.
Exegesis
Input followed by output requires seeks
The fseek(ft, 0, SEEK_CUR); statement is required by the C standard.
ISO/IEC 9899:2011 §7.21.5.3 The fopen function
¶7 When a file is opened with update mode ('+' as the second or third character in the
above list of mode argument values), both input and output may be performed on the
associated stream. However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by output without an
intervening call to a file positioning function, unless the input operation encounters end-of-
file. Opening (or creating) a text file with update mode may instead open (or create) a
binary stream in some implementations.
(Emphasis added.)
fgetc() returns an int
Quotes from ISO/IEC 9899:2011, the current C standard.
§7.21 Input/output <stdio.h>
§7.21.1 Introduction
EOF which expands to an integer constant expression, with type int and a negative value, that
is returned by several functions to indicate end-of-file, that is, no more input from a
stream;
§7.21.7.1 The fgetc function
int fgetc(FILE *stream);
¶2 If the end-of-file indicator for the input stream pointed to by stream is not set and a
next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the
stream (if defined).
Returns
¶3 If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the
fgetc function returns the next character from the input stream pointed to by stream.
If a read error occurs, the error indicator for the stream is set and the fgetc function
returns EOF.289)
289) An end-of-file and a read error can be distinguished by use of the feof and ferror functions.
So, EOF is a negative integer (conventionally it is -1, but the standard does not require that). The fgetc() function either returns EOF or the value of the character as an unsigned char (in the range 0..UCHAR_MAX, usually 0..255).
§6.2.5 Types
¶3 An object declared as type char is large enough to store any member of the basic
execution character set. If a member of the basic execution character set is stored in a
char object, its value is guaranteed to be nonnegative. If any other character is stored in
a char object, the resulting value is implementation-defined but shall be within the range
of values that can be represented in that type.
¶5 An object declared as type signed char occupies the same amount of storage as a
‘‘plain’’ char object.
§6 For each of the signed integer types, there is a corresponding (but different) unsigned
integer type (designated with the keyword unsigned) that uses the same amount of
storage (including sign information) and has the same alignment requirements.
§15 The three types char, signed char, and unsigned char are collectively called
the character types. The implementation shall define char to have the same range,
representation, and behavior as either signed char or unsigned char.45)
45) CHAR_MIN, defined in <limits.h>, will have one of the values 0 or SCHAR_MIN, and this can be
used to distinguish the two options. Irrespective of the choice made, char is a separate type from the
other two and is not compatible with either.
This justifies my assertion that plain char can be a signed or an unsigned type.
Now consider:
char c = fgetc(fp);
if (c == EOF)
…
Suppose fgetc() returns EOF, and plain char is an unsigned (8-bit) type, and EOF is -1. The assignment puts the value 0xFF into c, which is a positive integer. When the comparison is made, c is promoted to an int (and hence to the value 255), and 255 is not negative, so the comparison fails.
Conversely, suppose that plain char is a signed (8-bit) type and the character set is ISO 8859-15. If fgetc() returns ÿ, the value assigned will be the bit pattern 0b11111111, which is the same as -1, so in the comparison, c will be converted to -1 and the comparison c == EOF will return true even though a valid character was read.
You can tweak the details, but the basic argument remains valid while sizeof(char) < sizeof(int). There are DSP chips where that doesn't apply; you have to rethink the rules. Even so, the basic point remains; fgetc() returns an int, not a char.
If your data is truly ASCII (7-bit data), then all characters are in the range 0..127 and you won't run into the misinterpretation of ÿ problem. However, if your char type is unsigned, you still have the 'cannot detect EOF' problem, so your program will run for a long time. If you need to consider portability, you will take this into account. These are the professional grade issues that you need to handle as a C programmer. You can kludge your way to programs that work on your system for your data relatively easily and without taking all these nuances into account. But your program won't work on other people's systems.
You are not changing the 'i' in abc.txt, you are changing the next character after 'i'. Try to put fseek(ft, -1, SEEK_CUR); before your fputc('a', ft);.
After you read a 'i' character, the file position indicator of ft will be the character after this 'i', and when you write a character by fputc(), this character will be write at the current file position, i.e. the character after 'i'. See fseek(3) for further details.
After reading 'i' you need to "step back" to write to the correct location.
if(ch=='i')
{
fseek(ft, -1, SEEK_CUR);
fputc('a',ft);
}

why in c language EOF IS -1?

in c language i am using EOF .....why EOF IS -1 ? why not other value?
From Wikipedia:
The actual value of EOF is system-dependent (but is commonly -1, such as in glibc) and is unequal to any valid character code.
It can't be any value in 0 - 255 because these are valid values for characters on most systems. For example if EOF were 0 then you wouldn't be able to tell the difference between reading a 0 and reaching the end of file.
-1 is the obvious remaining choice.
You may also want to consider using feof instead:
Since EOF is used to report both end of file and random errors, it's often better to use the feof function to check explicitly for end of file and ferror to check for errors.
It isn't. It is defined to be an implementation-defined negative int constant. It must be negative so that one can distinguish it easily from an unsigned char. in most implementations it is indeed -1, but that is not required by the C standard.
The historic reason for choosing -1 was that the character classification functions (see <ctype.h>) can be implemented as simple array lookups. And it is the "nearest" value that doesn't fit into an unsigned char.
[Update:] Making the character classification functions efficient was probably not the main reason for choosing -1 in the first place. I don't know all the historical details, but it is the most obvious decision. It had to be negative since there are machines whose char type didn't have exactly 8 bits, so choosing a positive value would be difficult. It had to be large enough so that it is not a valid value for unsigned char, yet small enough to fit into an int. And when you have to choose a negative number, why should you take an arbitrary large negative number? That leaves -1 as the best choice.
Refer to details at http://en.wikipedia.org/wiki/Getchar#EOF_pitfall and http://en.wikipedia.org/wiki/End-of-file
Easily you can change the EOF value.
In C program define the macro for EOF=-1 in default,
So you mention EOF in your program, that default c compiler assign value for -1;
for example;
Just you try and get the result
#include <stdio.h>
#define EOF 22
main()
{
int a;
a=EOF;
printf(" Value of a=%d\n",a);
}
Output:
Value of a=22
Reason:
That time EOF value is changed
int c;
c = getchar();
while(!feof(stdin) && !ferror(stdin)) {
...
c = getchar();
}
You should be careful to consider the effect of end of file or error on any tests you make on these values. Consider this loop, intended to scan all characters up to the next whitespace character received:
int c;
c = getchar();
while(!isspace(c)) {
...
c = getchar();
}
If EOF is returned before any whitespace is detected then this loop may never terminate (since it is not a whitespace character). A better way to write this would be:
int c;
c = getchar();
while(!feof(stdin) && !ferror(stdin) && !isspace(c)) {
...
c = getchar();
}
Finally, it is worth noting that although EOF is usually -1, all the standard promises is that it is a negative integral constant with type int.

Resources