问题
*Note: I'm using windows, so EOF is ctrl + Z for me.
For a while I've noticed an EOF input seems to behave differently in isolation than it does when accompanied by other input. For example, ^Z
(the EOF command for windows in command prompt) and a^Z
seem to cause different behavior in the following code:
#include <stdio.h>
#define MAX 1000
int getline(char s[]);
main() {
int line;
char arr[MAX];
while( (line = getline(arr)) != EOF)
printf("%s",arr);
system("Pause");
return 0;
}
int getline(char s[])
{
int c, i = 0;
while ((c = getchar()) != EOF && c != '\n') {
s[i++] = c;
}
if (c == '\n') {
s[i++] = c;
}
else
return EOF;
s[i] = '\0';
return 1;
}
If I input ^Z
+ enter in the command prompt, the program predictably jumps to system("Pause");
However, if I input abc^Z
+ enter, nothing happens, as though EOF was ignored and a '\n'
command was never received. If, at this point, I press enter again, it shows the following:
I've been tinkering with and debugging this code and small variations of it for over an hour now and can't seem to find anything wrong with it. In theory, if I input abc^Z
+ enter, I expect the input to be interpreted as abcEOF\n
, which would give:
s[0] = 'a'
s[1] = 'b'
s[2] = 'c'
i = 3 when loop breaks from c = EOF
if (c == '\n') skipped since c = EOF
leads to else -> return EOF
in main(), line = EOF since that is what the function getline returned
while loop breaks because of above
system("Pause"); follows
Is there something wrong with my code that I'm overlooking or is there some quirk to EOF or command prompt that I should be aware of? I'm almost certain this isn't the only instance where mixing ^Z
with other values caused unintended behavior.
回答1:
Don't think of CTRL-Z as the end-of-file character, there is actually a real character with code point 26 (which is what you'd normally expect CTRL-Z to generate).
Instead, think of CTRL-Z as a way for your terminal device to indicate the end of the input stream to your program. If you were to read a real file of the disk and it contained CTRL-Z, it should keep going (though that may not be the case in certain implementations where you, for example, open it with the mode r
instead of rb
).
In Windows, that translation of CTRL-Z to the end-stream operation only happens when it appears at the start of the line which is why you're not getting EOF when you enter abcCTRL-Z
.
When you enter CTRL-Z on a character position that isn't the start of the line, it's treated as a real CTRL-Z, not a stream-closing operation. That's why you're getting that →
character, which is the printable character at code point 26.
回答2:
It is the normal behaviour of getchar..
getchar() is a standard function and requires you to press *ENTER* to get the input
Many compilers/platforms support the non-standard getch() that does not require ENTER.
EOF is not a character. The EOF is a macro that getchar() returns when it reaches the end of input or encounters some kind of error
来源:https://stackoverflow.com/questions/17162167/eof-behavior-when-accompanied-by-other-values