Many beginners are accustomed to using char variables to receive the return values of functions such as getchar, GETC, and fgetc. In fact, this is not correct, and it implies a fatal error. The return values of functions such as getchar are int type. When these functions fail to be read or the file is read, EOF is returned. EOF is a macro. The standard specifies that its value must be a negative constant of the int type. Generally, the compiler defines EOF as-1. This is where the problem occurs. Receiving the return values of functions such as getchar using the char type variable will lead to an error in EOF identification, or mistakenly mistake the good data for EOF or for good data. For example:
Int C;/* is correct. The Int type variable should be used to receive the return value of fgetc */
While (C = fgetc (FP ))! = EOF)
{
Putchar (C );
}
As shown in the preceding example, we often need to use a variable to receive the return values of functions such as fgetc, and then compare the variable with EOF to determine whether the file has been read. The above example is correct. Defining C as the int type ensures that it can correctly receive the EOF returned by fgetc, thus ensuring the correctness of this comparison. However, defining C as a char type can lead to unexpected consequences.
First, because the return values of fgetc and other functions are int type, when assigned to a char type variable, it will degrade, resulting in data truncation. For example:
---------------------------------
| Decimal | int | char |
| -------- | -------------- | ------- |
| 10 | 00 00 00 0a | 0a |
|-1 | FF |
|-2 | FF Fe |
---------------------------------
Here, we assume that int and Char are 32-bit and 8-bit respectively. From the table above, from int to Char, three bytes of data are lost. When we want to compare the char type with the int type, the char type will be automatically upgraded to the int type. The value after the char type is upgraded to the int type is different because it is signed Char or unsigned char. Unfortunately, if we do not use signed or unsigned to modify char, we do not know whether char refers to unsigned char or signed Char, because it is determined by the compiler. However, whether char is signed or unsigned, the fact that the return values of functions such as fgetc can be received using char variables cannot be changed. The only thing that can change is the consequence of this error. As we mentioned above, Char will be automatically upgraded to int when comparing the char and INT types. Let's take a look at the conversion of signed Char and unsigned char to int, their values are different:
---------------------------------------
| Char | unsigned | signed |
| ------- | --------------- | ------------- |
| 10 | 00 00 00 0a | 00 00 0a |
| FF | 00 00 FF |
| Fe | 00 00 00 Fe | FF Fe |
---------------------------------------
As shown in the table above, when char is unsigned, the value after converting it to int is a positive number. That is to say, if we define C as a char variable, and the default char of the compiler is unsigned char, the following expression will always be true.
(C = fgetc (FP ))! = EOF/* C is always a positive number, while the Standard stipulates that EOF is a negative number */
That is to say, the following loop is an endless loop.
While (C = fgetc (FP ))! = EOF)
{
Putchar (C );
}
After reading this, some readers may say, "it's okay to clearly define C as signed Char !" Unfortunately, it is still wrong to define C as signed Char. Assume that the value of a byte read by a function such as fgetc is FF, then the returned value is 00 00 ff. After this value is assigned to C, the value of C is changed to ff. Then, to compare the value of C with EOF, it is automatically upgraded to the value of int type, that is, FF. As a result, the following expressions are invalid.
If (C = fgetc (FP ))! = EOF)/* read the character whose value is FF, mistakenly believing that EOF */
That is to say, the following loop exits early without reading the file.
While (C = fgetc (FP ))! = EOF)
{
Putchar (C );
}
To sum up, it is wrong to use the char variable to receive the return values of functions such as fgetc. We must use the int variable to receive the return values of these functions, and then determine whether the received values are EOF. Only when the returned value is not EOF can we assign the value to the char variable.
Similarly, in C ++, receiving the return value of CIN. Get () with a char variable is also incorrect. However, it is correct to pass the char variable to CIN. Get as a parameter. For example:
Char c = cin. Get (); // error for the same reason
Char C;
Cin. Get (c); // correct