Windows Ctrl+;终端中的Z行为

Windows Ctrl+;终端中的Z行为,windows,c++11,iostream,windows-console,Windows,C++11,Iostream,Windows Console,如果在按Ctrl+Z之前输入字符,则必须按enter键两次,程序不会退出 ^Z Exiting 我一直将Ctrl+Z解释为EOF字符getline将继续,直到它到达这个字符,此时getline测试为false,我的程序将退出。我很好奇为什么我的程序会根据是否有前一个字符将Ctrl+Z解释为26,以及为什么在第二个示例中我必须按Enter键两次?26是平台上^Z的代码,^Z是终端的EOF标记,这是真的。代码小于32的字符是ASCII兼容平台的控制字符,我希望您知道这一点。26不是替代字符,它是实

如果在按Ctrl+Z之前输入字符,则必须按enter键两次,程序不会退出

^Z
Exiting

我一直将Ctrl+Z解释为EOF字符
getline
将继续,直到它到达这个字符,此时
getline
测试为false,我的程序将退出。我很好奇为什么我的程序会根据是否有前一个字符将Ctrl+Z解释为26,以及为什么在第二个示例中我必须按Enter键两次?

26是平台上^Z的代码,^Z是终端的EOF标记,这是真的。代码小于32的字符是ASCII兼容平台的控制字符,我希望您知道这一点。26不是替代字符,它是实际的控制代码,^Z或某些“bug”字符是替代字符
getline
读取输入,直到在流中遇到EOL(行尾,由ASCII指定为CR)或EOF(文件尾,流尾,指定为SUB)为止,因此^Z通过第二次调用
getline
读取。这种行为是绝对正确的

如果字符被立即发送到输入缓冲区或在某个刷新命令发生后发送到输入缓冲区,则由平台(或者更准确地说,由终端类型)定义。缓冲区刷新的通常原因是下线字符,这是您的输入(CR-回车)。这就是为什么程序在您的案例中输入后收到EOF。请注意,有些平台使用LF(换行符)作为下线,有些-一对LF+CR。C文字'\n'将正确翻译为特定的下线标记

请注意,您可以使用不同的分隔符:

s^Z

---
115
26
template<类图表、类特征、类分配器>
std::基本istream和getline(
标准::基本流和输入,
标准::基本字符串和str,
查特·德里姆);
带替换控件的ASCII表格+:

行开头的Ctrl+Z由Windows控制台本身处理,但奇怪的是,它只用于一般调用,而不是特定的
ReadConsole
调用。在这种情况下,read将
lpNumberOfBytesRead
返回为0,这就是C/C++运行时解释为EOF的内容。在第二个示例中,必须按两次enter键是很奇怪的。它将SUB(“\x1a”)字符保留在缓冲区中,并删除其后的所有内容,包括CRLF行结尾。如果它在结果中没有保持子,它几乎是可以理解的,因为Windows C和C++运行时把这个字符当作EOF标记。ISTM这里正确的行为应该是从
getline
返回行中前面的子项,而不是将其保留在缓冲区中并继续读取。
s^Z

---
115
26
template< class CharT, class Traits, class Allocator > 
std::basic_istream<CharT,Traits>& getline( 
         std::basic_istream<CharT,Traits>& input,
         std::basic_string<CharT,Traits,Allocator>& str,
         CharT delim );