'fin.get(ch);' 读取最后一个字符两次,而 'ch=fin.get();' 不在 'while(!fin.eof())' 循环中,为什么?[复制]

`fin.get(ch);` reads last character twice while `ch=fin.get();` not inside `while(!fin.eof())` loop why? [duplicate]

提问人:Abhishek Mane 提问时间:8/27/2021 更新时间:8/28/2021 访问量:482

问:

vicky.txt 文件

I was born in Hupari.

代码 -1

#include <iostream>
#include<fstream>
int main()
{
    char ch;
    std::ifstream fin;
    fin.open("vicky.txt", std::ios::in);

    while (!fin.eof())
    {
        fin.get(ch);
        std::cout<<ch;
    }
    fin.close();
    return 0;
}

输出

I was born in Hupari..

代码 -2

#include <iostream>
#include<fstream>
int main()
{
    char ch;
    std::ifstream fin;
    fin.open("vicky.txt", std::ios::in);

    while (!fin.eof())
    {
        ch=fin.get();
        std::cout<<ch;
    }
    fin.close();
    return 0;
}

输出

I was born in Hupari. 

为什么在使用它时会读取两个最后一个字符。另一方面,正确读取意味着只读取一次最后一个字符。fin.get(ch)ch=fin.get()

顺便说一句,还告诉返回类型?和 返回类型 对吗?fin.get(ch)fin.get()char

C++ 获取 文件处理 ifstream eof

评论

0赞 Eljay 8/28/2021
两者都不正确。也没有检查 EOF 的 .Dup:stackoverflow.com/a/26557243/4641116fin.get

答:

4赞 Yksisarvinen 8/28/2021 #1

这两个版本都是错误的。有关如何正确编码读取循环的更多详细信息,请参阅为什么 iostream::eof 在循环条件中(即 while (!stream.eof()))被认为是错误的?


现在,解释发生了什么。第一个版本使用 get() 的第二个重载。如果读取失败(例如,当到达文件末尾时),此方法将其参数保持不变,并设置标志。因此,您再次打印最后一个已读字符。

第二个版本使用 get() 的第一个重载。由于此版本必须返回一个字符,并且不能像其他版本那样保持不变,因此它返回一个能够返回特殊值(该值不得表示任何有效字符)。 通常等于 (as )。然后,你隐式地将其转换为 ,这将使它等于(或保持为 ,但为 8 位)。然后打印它。根据终端使用的代码页,它可以是 ÿ char、不间断空格或其他内容。您可能打印了不间断空格字符,或者其他一些不可见或不可打印的字符。intEOFEOF-1intchar255-1

评论

0赞 Abhishek Mane 8/28/2021
什么是返回类型?fin.get(ch)
1赞 Yksisarvinen 8/29/2021
@AbhishekMane 返回值是 ,即您调用该方法的同一流。这允许您链接调用。例如,像这样的链 - 可以让你在读取后检查值。或者,更好的版本仅在读取成功时运行。finfin.get(ch).eof()eofif(fin.get(ch))