【问题标题】:Why getline() doesn't accept a constant istream?为什么 getline() 不接受常量 istream?
【发布时间】:2014-02-24 20:20:05
【问题描述】:

这里是基本问题,我正在尝试学习iostream的基础知识。

我被告知要构建一个读取 const istream& 行的函数。即 validateFile(const istream& is)

我发现我不能使用带有 const istream& 作为第一个参数的函数 getline()。我想知道为什么。我以为我只是在阅读 istream,函数 getline() 会改变它吗?

是否有可能从恒定流中获取信息?

【问题讨论】:

  • 它从流中读取一行,所以它改变了它的状态。

标签: c++ constants iostream getline istream


【解决方案1】:

流的想法是顺序地从中读取一些数据,每次都推进其内部指针。通过推进此指针,您可以更改流对象。您无法从 const 流中读取信息(除非您 const-cast 它们,但这是您不应该做的事情)。

编辑: 实际上,我们并不关心隐藏在istream 接口后面的实际流对象是否使用了一些“内部指针”。准确地说,重要的是当你读取它时,流会改变它的状态,因为下次你读取它时,你会得到不同的结果(你从流中读取下一个东西)。如果给你一个const 对象,这意味着你不应该改变它的状态。

此外,您不能只从流中获取数据而不进行任何更改,这是有原因的。在文件流的情况下,您要从流中读取的下一个内容可能甚至不在内存中,流对象可能必须先从磁盘中读取它,更新其缓冲区等。(编辑: 但这不会改变对象的外部可见状态,所以实际上这不是一个好的论据。阅读 mutable 关键字以了解更多信息。)

【讨论】:

  • @MemyselfandI 你说得对,istream 只是一个接口,实际文件流是否使用一些指向其缓冲区的指针是实现细节。
【解决方案2】:

可以从const 流中获取数据,但您需要通过它管理的 streambuf 类进行读取:

#include <sstream>
#include <iostream>
#include <cstdio>

int main()
{
    const std::istringstream strm("Const stream");
    std::streambuf* buf = strm.rdbuf();

    char c;
    while ((c = buf->sbumpc()) != EOF)
        std::cout << c;
}

【讨论】:

  • 这应该被视为规范中的错误。 -1 反对愚蠢的投票。
  • 嗨,@JanHudec,我不同意。有 CONST STREAM 是一个错误! (恕我直言)。祝你有美好的一天:)
  • @jrok:显然拥有 const 流没有任何意义,但是当您拥有 const 流时,它不应该让您获得指向其缓冲区的非 const 指针。
【解决方案3】:

std::getline()(以及其他 I/O 函数)设置底层流状态以指示解析或格式化期间的错误。这就是为什么流不能是const-qualified。而且,流的width()在某些操作后会被重置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2020-12-25
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多