Mic*_*ler 4 c linux windows eof
我目前正在尝试使用以下内容结束while循环:
#include <stdio.h>
int main()
{
while(getchar() != EOF)
{
if( getchar() == EOF )
break;
}
return 0;
Run Code Online (Sandbox Code Playgroud)
}
当我按下CTRL+D我的Ubuntu时,它会立即结束循环.但在Windows上,我必须按CTRL+Z,然后按ENTER关闭循环.我可以摆脱ENTERWindows吗?
对于linux,EOF字符用ctrl+ 编写d,而在Windows上,当您enter通过ctrl+ 更改CRT库的内部状态后按下时,它由控制台编写z(此行为保留用于与旧系统的后向兼容性).如果我没错,它被称为软文件结尾.我不认为你可以绕过它,因为EOF字符实际上是getchar你按下时消耗的enter,而不是当你按ctrl+时z.
据报道在这里:
在Microsoft的DOS和Windows(以及CP/M和许多DEC操作系统)中,从终端读取将永远不会产生EOF.取而代之的是,节目识别出源是一个终端(或其他"字符设备")和解释给定保留的字符或序列作为指示剂文件结束-; 最常见的是这是一个ASCII Control-Z,代码26.一些MS-DOS程序,包括Microsoft MS-DOS shell(COMMAND.COM)和操作系统实用程序(如EDLIN)的一部分,处理Control-Z在文本文件中标记有意义数据的结尾,和/或在写入文本文件时将Control-Z附加到末尾.这样做有两个原因:
向后兼容CP/M. CP/M文件系统仅以128字节"记录"的倍数记录文件长度,因此按照惯例,如果有意义数据在记录中间结束,则使用Control-Z字符标记有意义数据的结尾.MS-DOS文件系统始终记录文件的确切字节长度,因此在MS-DOS上永远不需要这样做.
它允许程序使用相同的代码从终端和文本文件中读取输入.
其他信息也在这里报告:
一些现代文本文件格式(例如CSV-1203 [6])仍然建议将尾随的EOF字符作为文件中的最后一个字符追加.然而,键入控制+ Z没有嵌入的EOF字符到任何MS-DOS或Microsoft Windows中的文件,也没有这些系统的API使用的字符来表示文件的实际结束.
当使用内置文本文件读取基元(INPUT,LINE INPUT等)时,某些编程语言(例如Visual Basic)将无法读取"软"EOF,并且必须采用替代方法,例如以二进制模式打开文件或者使用文件系统对象来超越它.
字符26用于标记"文件结束",即使ASCII称之为替换,并且具有其他字符.
如果你修改你的代码:
#include <stdio.h>
int main() {
while(1) {
char c = getchar();
printf("%d\n", c);
if (c == EOF) // tried with also -1 and 26
break;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并且你测试它,在Windows上你会看到EOF(-1)它没有写在控制台中,直到你按下enter.那个a的beore ^Z是由终端模拟器打印的(我怀疑).从我的测试中,如果出现以
根据@eryksun的建议,我成功地为Windows编写了一个(可以做的很复杂的代码)代码,它改变了conhost的行为,实际上在按下ctrl+ 时"退出d".它不处理所有事情,它只是一个例子.恕我直言,这是尽可能避免的事情,因为可移植性小于0.此外,要实际正确处理其他输入案例,应编写更多代码,因为这些东西将stdin与控制台分离,你必须自己处理.
这些方法或多或少地起作用如下:
这是代码:
#include <windows.h>
#include <stdio.h>
#define Kev input_buffer[i].Event.KeyEvent // a shortcut
int main(void) {
HANDLE h_std_in; // Handler for the stdin
DWORD read_count, // number of events intercepted by ReadConsoleInput
i; // iterator
INPUT_RECORD input_buffer[128]; // Vector of events
h_std_in = GetStdHandle( // Get the stdin handler
STD_INPUT_HANDLE // enumerator for stdin. Others exist for stdout and stderr
);
while(1) {
ReadConsoleInput( // Read the input from the handler
h_std_in, // our handler
input_buffer, // the vector in which events will be saved
128, // the dimension of the vector
&read_count); // the number of events captured and saved (always < 128 in this case)
for (i = 0; i < read_count; i++) { // and here we iterate from 0 to read_count
switch(input_buffer[i].EventType) { // let's check the type of event
case KEY_EVENT: // to intercept the keyboard ones
if (Kev.bKeyDown) { // and refine only on key pressed (avoid a second event for key released)
// Intercepts CTRL + D
if (Kev.uChar.AsciiChar != 4)
printf("%c", Kev.uChar.AsciiChar);
else
return 0;
}
break;
default:
break;
}
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)