2015-05-12 2 views
5

Я тестировал, как читать данные из std::streamstring, но я ошибаюсь, мог ли кто-нибудь указать, в чем проблема? и дать правильный способ его прочитать?Чтение содержимого из строки stream

Мой код тестирования:

#include <iostream> 
#include <string> 
#include <sstream> 

#define BUFFER_SIZE 16 

int main(int argc, char ** argv) 
{ 

    std::stringstream ss; 
    ss << "Un texto con datos de ejemplo para probar la extacción de un stream"; 

    std::cout << "Stream contents: '" << ss.str() << "'" << std::endl; 

    char buffer[BUFFER_SIZE] = {0}; 

    std::streamsize read = 0; 

    do { 
     read = ss.readsome(buffer, BUFFER_SIZE - 1); 
     std::cout << "Read: " << ss.gcount() << std::endl; 
     std::cout << buffer << std::endl; 
     std::cout << "---" << std::endl; 
     std::fill(buffer, buffer + BUFFER_SIZE, 0); 
    } while (read > 0); 

    return 0; 
} 

И я получаю выход:

Stream contents: 'Un texto con datos de ejemplo para probar la extacci¾n de un stream' 
Read: 15 
Un texto con da 
--- 
Read: 15 
tos de ejemplo 
--- 
Read: 15 
para probar la 
--- 
Read: 15 
extacci¾n de un 
--- 
Read: 5 
stre 
--- 
Read: 0 

--- 

Как вы можете заметить, что последняя операция чтения читает только 5 символов оставляя два последних «утра «хотя он должен был прочитать его. Мне не хватает сотового?

+0

Думаю, вам нужно работать с версиями потоков и строк 'wchar_t'. – Nawaz

+1

Замена '' правильного результата 'o' на тот же результат. Зачем мне нужно работать с 'wchar_t'? –

+1

Я скопировал ваш код в .cpp-файл и скомпилировал его с помощью g ++ без аргументов. На моей машине весь поток печатается без усечения, но первое чтение только захватывает один символ. Я использую gcc 4.9.2 и glibc 2.21-3. –

ответ

3

На самом деле, readsome выполняет только чтение available characters и что это зависит от платформы, поэтому разрешено возвращать 0, пока в потоке все еще есть символы, и последующий вызов, вероятно, может вернуть отсутствующие символы. Чтобы получить все доступные данные, я бы предпочел использовать read в сочетании с gcount, чтобы получить количество символов, которые вы читаете.

do { 
    ss.read(buffer, BUFFER_SIZE - 1); 
    read=ss.gcount(); 
    std::cout << "Read: " << ss.gcount() << std::endl; 
    std::cout << buffer << std::endl; 
    std::cout << "---" << std::endl; 
    std::fill(buffer, buffer + BUFFER_SIZE, 0); 
} while (read > 0); 

Просто для уточнения:
Хотя я полагаю, behavoir вы наблюдали допускается стандартом, я не понимаю, почему реализация должна вести себя так, когда входной поток основан на строковый литерал (im не знакомы с деталями реализации потоков). Что вы могли бы проверить, если read действительно соответствует rdbuf()->in_avail(), и если это не так, это может быть ошибка компилятора.

+0

Выполнение этих изменений решает проблему. Итак, 'readsome' следует использовать в пуле? (так как может вернуть 0 событие, хотя остается содержимое слева). –

+0

@ Javier Mr: Я действительно не знаю. Насколько я могу судить, идея чтения readsome - предоставить вам все символы, которые доступны без потенциально блокирующего системного звонка. Поэтому я не уверен, если вы получите все данные вообще. С другой стороны, я также не понимаю, почему конкретная реализация VC++ 2008 не даст вам всех данных из локального строкового объекта. Однако, если вы говорите о пулах потоков, я бы определенно сказал «нет», поскольку это не потокобезопасно, поэтому вам придется сериализовать его в любом случае. – MikeMB

+0

Да, я имел в виду однопоточные последовательные звонки. Я понимаю цель «readsome» блокировать как можно меньше. Однако я протестировал изменение условия do-while на '! Ss.eof()' и, по-видимому, 'readsome' никогда не читает весь поток, также проверял' in_avail' и начинает со значения 50 и в каждом вызове уменьшается без чтения последние. Благодарю. –

Смежные вопросы