2014-09-05 2 views
1
#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); 
    } 
} 

Когда я запускаю эту программу, возникает некоторая неожиданная ситуация с^Z (Ctrl + z), которую я буду использовать для указания EOF.(C/C++) EOF в windows7

Ввод "hello \ n" выполняет цикл while в 'fcopy' для печати того же.

"^ Z \ n" завершает работу программы.

Но если я введу «blahblah^Zasdfasdf \ n», в то время как я ожидал, что программа напечатает «бла-бла» и закончится, она напечатает «blahblah →» с помощью маленькой стрелки и ждет моего ввода. Все, что я записываю здесь, будет скопировано точно так же; он, похоже, повторно выполняет цикл, отсекая все, что написано после «^ Z».

in: hello 
out: hello 

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

in: ^Z 
termination 

Может ли кто-нибудь объяснить, почему программа работает именно так? Спасибо за любую помощь, заранее.

ответ

3

В целом я ожидал бы, что вы должны ждать^Z, а не EOF.^Z является символом 0x1A ASCII (http://en.wikipedia.org/wiki/Substitute_character). Кроме того, вам обязательно нужно проверить EOF, так как файл может закончиться без^Z

Похоже, что по какой-то причине консольные приложения интерпретируют^Z как EOF, когда строка пуста (я не уверен, почему, хотя - это может быть легитимным поведение или просто ошибка, как это было предложено в https://connect.microsoft.com/VisualStudio/feedback/details/798951/c-getc-breaks-when-encountering-character-26-or-1a-hex-ascii-sub)

но следующий код фиксирует это:

#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); 
    } 
} 
5

Это потому, что программа терминала Windows, которая является тем, что читает ваш ввод с клавиатуры и передает ее в вашу программу, обрабатывает Ctrl + Z вот так. Это означает только «конец сигнала ввода» при нажатии в начале строки.

Обратите внимание, что EOF в C не является фактическим («физическим») символом, это внеполосная сигнализация, указывающая, что «не было символа, который должен быть прочитан, так как файл закончился».