【问题标题】:Why does std::istream::ignore discard characters?为什么 std::istream::ignore 会丢弃字符?
【发布时间】:2018-02-22 07:50:48
【问题描述】:

CPlusPlus websitestd::istream::ignore,上面写着

istream& ignore (streamsize n = 1, int delim = EOF);

提取和丢弃字符

从输入中提取字符 序列并丢弃它们,直到已经有 n 个字符 提取,或比较等于 delim。

为什么它说它丢弃它们而不是退回它们

编辑

根据要求,这里是有问题的特定代码。它是一个回调函数,服务端,处理发送的客户端文件(_data

static void loadFile (const std::string &_fileName, std::vector<char> &_data)                                                                                            
{
    std::ifstream ifs;
    ifs.exceptions(std::ifstream::failbit);
    ifs.open(_fileName, std::ifstream::in | std::ifstream::binary);
    auto startPos = ifs.tellg();
    ifs.ignore(std::numeric_limits<std::streamsize>::max());
    auto size = static_cast<std::size_t>(ifs.gcount());
    ifs.seekg(startPos);
    _data.resize(size);
    ifs.read(_data.data(), size);
    std::cout << "loaded " << size << " bytes" << std::endl;
}   

【问题讨论】:

  • 我不认为我理解这个问题......它丢弃它们,因为它们被扔掉,你不'在您编写的任何代码中都看不到或使用它们。
  • 同意这个问题有点不清楚。也许您可以解释为什么您认为“退货”更合适
  • 这甚至是函数 name 的一部分,用于ignore 事物。
  • 这是读取行首的常用方法,然后忽略(并丢弃)该行的其余部分。当使用格式化输入(&gt;&gt; 运算符)时,它对文本文件有意义,但不适用于一般的“二进制”文件或使用 read 读取更大的块时。没有更多的上下文,我们只能猜测得很差,即使有上下文,我们仍然只能猜测。只有编写代码的人才能可靠地回答您的问题。
  • 我认为这个问题有可能成为一个好问题,如果你重新表述它以询问你发布的 sn-p 中ignore 的使用(而不是为什么一个名为 ignore 的函数) ,好吧,忽略输入)。

标签: c++ istream


【解决方案1】:
auto startPos = ifs.tellg();

这将位置存储在(刚刚打开的)文件的开头。

ifs.ignore(std::numeric_limits<std::streamsize>::max());

这会读取整个文件(直到 EOF)并丢弃读取的内容。

auto size = static_cast<std::size_t>(ifs.gcount());

gcount 返回上次未格式化输入操作读取的字符数,在本例中为ignore。由于ignore读取文件中的每一个字符,这就是文件中的字符数。

ifs.seekg(startPos);

这会将流重新定位到文件的开头,

_data.resize(size);

...分配足够的空间来存储整个文件的内容,

ifs.read(_data.data(), size);

最后将其再次读入_data

【讨论】:

    【解决方案2】:

    为什么它说它丢弃它们而不是返回它们?

    因为还有其他函数可以返回它们。见std::istream::getlinestd::getline


    更新

    您更新后的帖子中以下几行的全部目的是获取文件的大小。

    auto startPos = ifs.tellg();
    ifs.ignore(std::numeric_limits<std::streamsize>::max());
    auto size = static_cast<std::size_t>(ifs.gcount());
    

    这是我第一次看到使用istream::ignore() 来做到这一点。您还可以使用以下内容来获取文件的大小。

    // Find the end of the file
    ifs.seekg(0, std::ios::end);
    
    // Get its position. The returned value is the size of the file.
    auto size = ifs.tellg();
    

    【讨论】:

    • 那么像ifs.ignore(std::numeric_limits&lt;std::streamsize&gt;::max()); 这样的行会什么都不做吗?
    • @puk,它会做点什么。它会读取字符并丢弃它们。这不是什么都不做。
    • 最多std::numeric_limits&lt;std::streamsize&gt;::max() 字符。 (很多!)这可能是一个 XY 问题 -- 你为什么要从一开始就丢弃它们?
    • @DavidC.Rank 不是“至少”而是“最多”;)
    • 实际上,无论文件大小如何,它都会丢弃所有这些。 istream::ignorestd::numeric_limits&lt;std::streamsize&gt;::max() 视为一个特殊值,这意味着忽略整个流(直到指定的分隔符)。
    猜你喜欢
    • 1970-01-01
    • 2011-07-03
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    相关资源
    最近更新 更多