练习8.1

发布时间 2023-07-11 22:31:52作者: yuzuki_n

题目:写一个函数,接受一个istream&参数,返回值也是istream&。该函数必须从给定流中读取数据,直至遇到文件结束标识符时停止。将他读取的函数打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。

#include <iostream>
#include <istream>
#include <string>

using namespace std;

istream& func(istream& is)
{
    string line;
    while (std::getline(is, line))
    {
        cout << line;
    }
    is.clear();
    return is;
}

int main()
{
    func(cin);
    return 0;
}

上面是我写的代码,总之我不理解什么事复位流,复位流有什么意义。

我找到一个网站说明流的状态
https://www.learncpp.com/cpp-tutorial/stream-states-and-input-validation/

流有好几种状态,用标志位来表示。不过这里的分了badbit和failbit(ta们这么做一定有他们的用意( )
image

还提供了一组函数方便访问这些位
image

如果流的操作发生了什么错误,并且设置了goodbit以外的值,后续对流的操作会无效,需要clear一下流(现在我知道对流的复位有什么用了)。

看看书上是怎么写的

#include <iostream>
#include <stdexcept>

using namespace std;

istream& f(istream& in)
{
    int v;
    while (in >> v, !in.eof())
    {
        if (in.bad())
        {
            throw runtime_error("IO流错误");
        }
        if (in.fail())
        {
            cerr << "数据错误,请重试: " << endl;
            in.clear();
            in.ignore(100, '\n');
            continue;
        }
        cout << v << endl;
    }
    in.clear();
    return in;
}

int main()
{
    cout << "请输入一些整数, Ctrl+z 结束" << endl;
    f(cin);
    return 0;
}

书上的代码就比我的完善多了,首先通过in.bad()检查badbit有没有设置,有的话就直接抛出异常。然后in.fail()检查failbit位有没有被设置(例如我输入字符,在这个要求输入整数的例子里就会导致failbit被设置),如果被设置就clear复位流。in.ignore(100, '\n');我查了一下

The cin.ignore() function is used which is used to ignore or clear one or more characters from the input buffer.

有个回答https://stackoverflow.com/questions/33861470/what-cin-ignore-does-exactly 也解释了这个问题

https://blog.csdn.net/qq_27278957/article/details/88917911

大概就是忽略掉100个字符,或者碰到'\n'就停止忽略字符。