Я видел много вопросов о методе peek, но мой касается темы, которая была бы почти очевидной, но тем не менее (я думаю) интересной.
Предположим, у вас есть бинарный файл, который вы хотите прочитать, и вы решили вывести его целиком в память программы и использовать объект 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
, Это может иметь встроенные NUL, но если вы передадите buffer
и это массив символов или char*
, string
конструктор, который вы неявно вызываете, будет использовать strlen
-стиль определения длины ASCIIZ для определения объема загружаемых данных. Вместо этого вы должны явно указать размер буфера — что-то вроде:
std::string str(buffer, bytes);
std::istringstream is(str);
Тогда ваш while(!is.eof()
бодрый … есть сотни С.О. Q&А об этом вопросе; один наугад — Вот.