简体   繁体   中英

(C/C++) EOF in windows7

#include <cstdio>

void fcopy(FILE* from, FILE* to);

int main()
{
    fcopy(stdin, stdout);
    return 0;
}

void fcopy(FILE* from, FILE* to)
{
    int c;
    while ((c = getc(from)) != EOF) {
        putc(c, to);
    }
}

When I run this program, some unexpected behaviour happens with ^Z (Ctrl+z), which I would use to indicate EOF.

My input of "hello\\n" executes the while loop in 'fcopy' to print the same.

"^Z\\n" ends the program.

But if I input "blahblah^Zasdfasdf\\n", while I expected the program to print "blahblah" and terminate, it prints "blahblah→" with a little arrow and waits for my input. Whatever I write down here will be copied down exactly the same; it seems to re-execute the loop while cutting away anything written after '^Z'.

in: hello
out: hello

in: hello^Z
out/in: hello→?? // "??" is my input
out: ??

in: ^Z
termination

Could anyone please clarify why the program works that way? Thanks for any help, in advance.

This is because the Windows terminal program, which is what is reading your keyboard input and passing it on to your program, is handling Ctrl+Z like that. It only means "signal end of input" when pressed at the start of a line.

Note that EOF in C does not represent an actual ("physical") character, it's out-of-band signalling to indicate that "there was no character to be read, since the file has ended".

In general I would expect you that you should wait for ^Z and not EOF. ^Z is 0x1A ASCII character ( http://en.wikipedia.org/wiki/Substitute_character ). Also, you should definitely also check for EOF since file can end without ^Z

It seems that for some reason, console applications interpret ^Z as EOF when line is empty (I'm not sure why though - This could be legitimate behavior or simply a bug as suggested in https://connect.microsoft.com/VisualStudio/feedback/details/798951/c-getc-breaks-when-encountering-character-26-or-1a-hex-ascii-sub )

But the following code fixes it:

#include <cstdio>

#define CTRL_Z_SUB 0x1A // CTRL_Z substitue ASCII key

void fcopy(FILE* from, FILE* to);

int main()
{
    fcopy(stdin, stdout);
    return 0;
}

void fcopy(FILE* from, FILE* to)
{
    int c = getc(from);

    while (c != EOF && c != CTRL_Z_SUB) {
        putc(c, to);
        c = getc(from);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM