【转】C++ 文件结束符

转载自:
http://blog.163.com/zhuandi_h/blog/static/1802702882012210114352789/“>c++文件结束符

问题描述:windows下

int main()

{

string str;

while(cin>>str);

cout<<"\n"<<"end"<<endl;

}

控制台输入多个字符串后,输入文件结束符crtl-Z,并未使while循环结束,该如何跳出while循环?

解决方法:

方法1:回车 - ctrl-z - 回车

方法2:改代码,设置自己的文件结束符
String a;
while((cin>> a)&&a!=’X’)
X可以为自己设置的文件结束符。

原因解析:

当从键盘输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin.get()就会 检测输入缓冲区中是否有了可读的数据。cin.get()还会对键盘上是否有流结束标识的Ctrl-z或者ctrl-d键按下做出检查,其检查的方式有两种,阻塞式以及非阻塞式。

windows系统一般采用阻塞式检查ctrl-z,Unix/Linux系统下一般采用非阻塞式的检查ctrl-d.

阻塞式检查方式是指只有在回车键按下之后才对此前是否有ctrl-z组合键按下进行检查。另外,如果输入缓冲区中有可读的数据则不会检测ctrl-z,因为有可读数据,说明还未到流的末尾。需要注意的时,ctrl-z产生的不是一个普通的ascii字符,因此ctrl-z不会跟其他从键盘输入的字符一样能够存放在输入缓冲区中。因此,若使ctrl-z产生作用,输入ctrl-z之前不应输入任何字符,即输入回车键把之前输入的字符全部送入缓冲区中后,紧接着应输入ctrl-z,然后输入回车键,告知系统检测流结束符ctrl-z.

非阻塞式是指按下ctrl-d之后立即响应的方式。如果在ctrl-d输入之前已经从键盘输入了字符,则ctrl-d相当于回车,即把这些字符送到了输入缓冲区供读取使用,此时ctrl+d不在起流结束符的作用。若ctrl-d输入值钱没有任何键盘输入,则ctrl-d就是流结束的信号。

windows 下ctrl-z使用举例说明如下:

从键盘上输入abcd^z 再输入回车键后,系统处理如下:因为回车的作用,前面的abcd等字符被送到输入缓冲区中,而^z不会产生自负,因此不会存储到缓冲区中。这是,cin.get()检测到输入缓冲区中已经有数据存在,就不会检测有无^z存在,cin.get()从缓冲中读取相应的数据,如果读取完了,则输入缓冲区重新边为空,cin.get()等待新的输入,可见尽管有ctrl-z输入,但是之前有其他字符,系统并未监测到流结束符。

因此输入流结束符的条件就是:^z之前不能有任何字符输入(回车键除外),然后再用回车键通知系统做流结束符检测。

### C++文件结束标志 EOF 的理解 在 C++ 中,`EOF` 并不是一个实际存在于文件中的标记。当尝试从输入流中读取数据失败时(例如因为已到达文件末尾),才会设置 `eof()` 标志位[^1]。 对于 `ifstream` 流对象而言,在每次试图执行读取操作之前并不会自动检查是否处于文件末尾位置;相反,只有当一次读取请求无法成功完成——即确实已经位于文件末端而无更多可读内容时——此时再调用成员函数 `eof()` 才能获得 true 值作为响应[^3]。 因此,在编写循环来逐次处理文件各行或其他单位的数据片段时,应当先尝试进行读取动作并立即检验该操作的结果状态,而不是单纯依赖于事前询问当前是否已达文档尽头: ```cpp #include <fstream> #include <iostream> #include <vector> using namespace std; int main(){ ifstream fin("example.txt"); vector<vector<double>> vecs; while(true){ vector<double> vec(8,0); bool allReadSuccessfully = true; for(auto& d : vec){ if(!(fin >> d)){ allReadSuccessfully = false; break; } } if(!allReadSuccessfully && !fin.eof()){ cerr << "Error reading file." << endl; return 1; } if(fin.eof()){ cout << "read over" << endl; break; } vecs.push_back(vec); } // 继续后续代码... } ``` 上述例子展示了更稳健的方法去遍历文件直到其真正结束,并且能够区分正常的文件结尾和其他可能发生的错误情况。 #### 关键点总结: - `EOF` 不是物理上存储于文件内的特殊字符或符号; - 成员方法 `eof()` 只有在最近的一次 I/O 操作因达到文件末尾未能成功之后才会返回 true; - 应优先考虑通过测试具体读取命令的成功与否来进行控制流程的设计,而非直接查询 `eof()` 来决定何时停止读取。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值