首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cin.eof()和feof(stdin)不一致

cin.eof()和feof(stdin)不一致
EN

Stack Overflow用户
提问于 2018-04-17 22:26:34
回答 1查看 379关注 0票数 2

feof(stdin)cin.eof()会产生不一致的结果吗?我希望他们不会这样做,但我猜我遗漏了一些东西。标准对此有什么规定吗?

考虑下面的例子,当没有输入的时候。这可以通过在终端中输入EOF的快捷键,或者通过在/dev/null (Unix)上重定向输入,或者在ideone.com上使用空的标准输入序列...

代码语言:javascript
复制
#include <cstdio>
#include <iostream>

int main() {
    using namespace std;

    char ch;
    cin >> ch;

    cin.clear();

    cout << boolalpha
         << "feof(stdin): " << bool(feof(stdin)) << endl
         << "cin.eof(): " << cin.eof() << endl;
}

输出:

代码语言:javascript
复制
feof(stdin): true
cin.eof(): false
EN

回答 1

Stack Overflow用户

发布于 2018-04-17 22:56:01

好吧,这没什么好惊讶的。

std::cin实际上是在C++库中定义的,但是stdin是在C标准库中定义的,C标准库是C++的成员,主要是出于兼容性的原因。

C++17的草案n4659说:

30.4.3 窄流对象 [narrow.stream.objects] istream cin; 1 对象 cin 控制来自与 (30.11.1) 中声明的对象 stdin 关联的流缓冲区的输入。

之后的版本:

30.11 C 库文件 [c.files] 30.11.1 标题 <cstdio> 概要 [cstdio.syn] ... 1 头文件<cstdio>的内容和含义与C标准库头文件<stdio.h>相同。

这意味着cin是一个包装底层stdin C文件对象的C++流。因此,当您在到达文件结尾后尝试从 cin读取字符时,cin将从stdin请求它,stdin将报告文件结束状态,并且cinstdin都将设置其内部文件结束标志。然后,对cin.clear()的调用将清除C++流标志,但未指定它是否对stdin对象内部标志进行了操作。

所以你要为C++ cin对象和C stdin对象之间缺乏同步负责。

现在要详细了解从您的想法中复制的代码中发生了什么:

代码语言:javascript
复制
#include <cstdio>
#include <iostream>

// first type the shortcut for EOF, then a single character

int main() {
    using namespace std;

    char ch;
    cin >> ch;             // 1

    cin.clear();           // 2

    cout << boolalpha      // 3
         << "feof(stdin): " << bool(feof(stdin)) << endl
         << "cin.eof(): " << cin.eof() << endl;

    ch = char(getchar());  // 4
    cout << ch << endl;    // 5

    cout << boolalpha      // 6
         << "feof(stdin): " << bool(feof(stdin)) << endl
         << "cin.eof(): " << cin.eof() << endl;
}

//1 :从cin读取字符(忽略字符):cin从stdin内部读取,stdin找到文件结尾,设置其内部EOF标志,并将文件结束条件返回给cincin设置自己的EOF标志

//2 :清除cin上的EOF标志,stdin保持不变(在此实现中,因为标准AFAIK未指定行为)

//3 :不出所料,feof(stdin)为真,cin.eof()为假

//4 :您从stdin读取了一个字符(此处未涉及cin)。由于您已经在文件的末尾,getchar返回整数常量EOF = -1。但是,当您强制转换为char -1并转换为'\xff'时,ASCII char DEL

//5:'\xff'不是有效的UTF8序列,并且ideone将其显示为unicode替换字符�

//6:feof(stdin)仍然为true: C文件已经到达文件末尾,cin.eof()仍然为false,因为//3之后没有任何更改

TL/DR:一切都符合预期:底层文件到达文件末尾,getchar()返回EOF,并且设置了eof标志。简单地说,cin.eof()是假的,因为您显式地清除了cin标志,并且以后永远不会使用它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49880746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档