我正在学习C ++并试图理解为什么EOF字符(Windows上的Ctrl + Z)如果放在一行的末尾就不会破坏while循环。
我的代码:
int main() {
char ch;
while(cin >> ch) {
cout << ch;
}
}
当我输入^ Z时,循环中断。但是当我输入12 ^ Z时,它没有。为什么?
我正在学习C ++并试图理解为什么EOF字符(Windows上的Ctrl + Z)如果放在一行的末尾就不会破坏while循环。
我的代码:
int main() {
char ch;
while(cin >> ch) {
cout << ch;
}
}
当我输入^ Z时,循环中断。但是当我输入12 ^ Z时,它没有。为什么?
C和C ++标准允许文本流完成非常邪恶的事情 文字模式,这是默认值。这些Unholy Things包括内部换行标记和外部换行控制字符之间的转换,以及将某些字符或字符序列视为表示 文件结束。在Unix-land中它还没有完成,但在Windows-land中已经完成了,因此代码只能与原始的Unix-land约定相关。
这意味着在Windows中,无法编写可将其输入精确复制到其输入的可移植C或C ++程序。
在Unix-land中,这根本不是问题。
在Windows中,由单个[Ctrl Z]组成的行按照惯例是文件结束标记。这不仅在控制台中,而且在文本文件中(取决于工具)。 Windows从DOS继承了这一点,后者继承了CP / M的一般思想。
我不确定CP / M从哪里得到它,但它只是 类似,完全不一样!,作为Unix'[Ctrl D]。
在Unix-land中,文件结尾的一般约定就是“不再有数据”。在控制台中,[Ctrl D]默认情况下会立即将您输入的文本发送到等待程序。如果还没有在行上键入任何内容,则会发送0个字节,并且按照惯例,返回0个字节的读取会遇到文件结尾。
主要区别在于Windows内部文件标记的文本末尾 数据,这可能发生在一个文件中,而在Unix内部则是这样 缺乏数据,不能在文件中出现。当然,Windows还支持文本的普通文件结尾(不再有数据!)。这使事情变得复杂 - Windows更复杂。
#include <iostream>
using namespace std;
int main()
{
char ch;
while(cin >> ch) {
cout << 0+ch << " '" << ch << "'" << endl;
}
}
您将无法在C ++标准中找到问题的答案。
cin >> ch
只要既没有文件结束条件也没有输入错误,它将是一个“真实”条件。语言未指定如何触发文件结束条件,并且它可以并且将随操作系统的不同而不同,甚至可以在同一操作系统中使用配置选项。 (例如,类Unix系统默认使用control-D,但可以通过 stty
命令。)
Windows使用Control-Z触发文本输入流的文件结束条件;除了在一行的开头,它恰好不会这样做。
Unix的行为有点不同;它在行的开头使用Control-D(默认情况下),或 二 控制-Ds在一条线的中间。
对于Unix,这仅适用于从终端读取的情况;如果您正在从文件中读取,则control-D只是另一个非打印字符,并且它不会触发文件结束条件。 Windows似乎将control-Z识别为文件结束触发器,即使从磁盘文件中读取也是如此。
底线:不同的操作系统表现不同,主要是出于模糊的历史原因。 C ++旨在处理这些行为中的任何一种,这就是为什么它没有具体说明某些细节。
这是由cin >> ^ Z将评估为false引起的。
更详细:cin.eof()将返回true,所以 while,隐式调用eof()将返回false 因此结束循环。
如果你输入12 ^ Z,eof()将返回false,因为它可以解析 一个有效的inputvalue,因此它不会停止循环。
您可能也对此SO感兴趣: