boost :: iostreams :: stream ‹boost :: iostreams :: array_source› не устанавливает EOF

Образец:

namespace  boostio = boost::iostreams;
boostio::stream<boostio::array_source> memStream(arr);


while (!memStream.eof())
{
    char tst[2];

    memStream2.readsome(tst, 2);
}

Здесь я инициализирую memstream массивом символов, но цикл while никогда не заканчивается. В чем проблема ?

РЕДАКТИРОВАТЬ: использование метода чтения потока работает должным образом. Использование чего-либо еще (включая оператор >>) недопустимо


person Gmt    schedule 05.12.2012    source источник
comment
memStream инициализируется неинициализированным массивом tst[2] - это может быть источником бесконечного цикла. Может помочь объявление и присвоение массиву значимого значения.   -  person damienh    schedule 05.12.2012
comment
@damienh, это просто для использования readsome. tst - это просто пункт назначения. ему все равно, что там при копировании.   -  person Gmt    schedule 05.12.2012
comment
У меня такая проблема при использовании оператора ››. Он работает только при использовании чтения, например. memStream2.read (tst, 2).   -  person Gmt    schedule 05.12.2012
comment
Никогда, никогда не вызывайте eof как условие завершения цикла. Существует множество причин отказа, не относящихся к EOF. См. latedev.wordpress.com/2012/12/04/all- about-eof   -  person Billy ONeal    schedule 06.12.2012


Ответы (2)


Есть две проблемы с использованием readsome () так, как вы делаете, помимо общего комментария, что это совершенно необязательно.

  1. Цель readsome() - получить следующие n байтов из тех данных, которые уже были загружены из источника символов во внутренний буфер потока последним вызовом rdbuf()->underflow(). Когда поток создается, он (в данном случае) не пытается немедленно читать из источника, его буфер пуст. readsome () ничего вам не даст.

    edit: технически в этом случае он возвращается к (также совершенно необязательному) showmanyc(), чтобы узнать, сколько данных доступно в источнике данных, но в этой реализации showmanyc возвращает «не уверен» (ноль).

  2. Даже если вы заполните буфер потока (обычным read () или get () и т. Д.), Readsome не установит никаких флагов потока, когда достигнет конца буфера потока: он не знает, есть ли в нем больше данных. источник (потому что showmanyc() не говорит).

На моих тестах работает следующее:

#include <iostream>
#include <complex>
#include <iomanip>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/array.hpp>

int main()
{
    namespace  boostio = boost::iostreams;

    char arr[10] = "example";
    boostio::stream<boostio::array_source> memStream(arr);

    char c;
    while(memStream.get(c)) // prime the buffer by reading 1 char
    {
        std::cout << c;
        char tst[2];
        while(memStream.readsome(tst, 2) > 0) // read some more
            for(int n = 0; n < memStream.gcount(); ++n)
                std::cout << tst[n];
    }
    std::cout << '\n';
}

При ближайшем рассмотрении iostreams хорошо разбирается в этом вопросе, и когда я читаю первый символ, он помещает внутренние указатели потокового буфера непосредственно в массив, поэтому в этом случае все, что осталось прочитать, можно получить из readsome ().

Теперь, что касается оператора >>, memStream >> setw(2) >> tst; у меня отлично работает (надеюсь, вы вспомнили о setw при использовании >> в массиве !!), несмотря на использование условия ошибочного цикла «while (! Stream.eof ()) `. Вам нужно будет предоставить тестовый пример, демонстрирующий проблему, с которой вы столкнулись с оператором >>

person Cubbi    schedule 06.12.2012
comment
При использовании оператора ›› пробовал например. в то время как (! memStream2.eof ()) {int t = 0; memStream2 ›› t; } - person Gmt; 06.12.2012
comment
@Gmt попробуйте правильный цикл ввода-вывода: int t; while(memStream2 >> t) { } - person Cubbi; 06.12.2012
comment
который устанавливает неудачный бит (я думаю), и у меня даже нет возможности прочитать что-либо в t - person Gmt; 06.12.2012

Вы, наверное, делаете tst >> memStream2;. Вам нужно сделать memStream2 >> tst; как в std::cin >> var;

person Etherealone    schedule 01.07.2015