peek() istringstrem 类中的行为

peek() behavior in istringstrem class

本文关键字:istringstrem peek      更新时间:2023-10-16

我在窥视方法上看到了很多问题,但我关注的是一个几乎显而易见的主题,但仍然(我认为(很有趣。

假设您有一个要读取的二进制文件,并且您选择在程序内存中将其作为一个整体启动,并使用 istringstream 对象来执行读取。

例如,如果您正在搜索流中给定字节的位置,则反复访问硬盘会浪费时间和资源......

但是一旦你创建了 istringstream 对象,任何最终的 NULL 字节都是被视为EOF信号。

至少这是在以下短代码中发生在我身上的事情:

                 // obvious omissis
                 std::istringstream is(buffer);
                 // where buffer is declared as char *
                 // and filled up with the contents of
                 // a binary file
                 char sample = 'a';
                 while(!is.eof() && is.peek() != sample)
                   { is.get(); }
                 std::cout << "found " << sample << " at " << is.tellg() << std::endl;

此代码不适用于 g++ 4.9 和 clang 3.5假设在匹配之前buffer内部存在空字节可以找到sample,因为该空字节设置eof位。

所以我的问题是:这种方法是要完全避免的,还是有某种方法可以教peek空字节"不一定"是流的末尾?

如果你看一下你的std::istringstream构造函数,你会发现(2(需要std::string。 这可以有嵌入式 NULL,但是如果您传递buffer并且它是一个字符数组或char*,则隐式调用的string构造函数将使用strlen样式的 ASCIIZ 长度确定来确定要加载的数据量。 相反,您应该显式指定缓冲区大小 - 如下所示:

std::string str(buffer, bytes);
std::istringstream is(str);

那么你的while(!is.eof()是笨拙的...关于这个问题有数百个 SO 问答;一个随机 - 这里。