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