Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading contents from a stringstream

I was testing how to read data out of an std::streamstring but I'm getting it wrong, could anyone point out what's the problem? and give a correct way to read it?

My testing code is:

#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;
}

And I'm getting the output:

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

---

As you may notice the last read operation reads only 5 characters leaving out the last two 'am' even though it should have been able to read it. Am I missing somtehing?

like image 663
Javier Mr Avatar asked Oct 19 '22 11:10

Javier Mr


1 Answers

Actually, readsome does only read the immediately available characters and what that is depends on the platform, so it is well allowed to return 0 while there are still characters in the stream and a subsequent call could probably return the missing characters. To get all available data, I'd rather use read in combination with gcount to get the Number of characters you read.

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 );

Just for clarification:
While I believe, the behavoir you observed is allowed by the standard, I don't see why the implementation should behave like this when the input stream is based on a string literal (im not familiar with the implementation details of streams). What you could check is, if read actually corresponds to rdbuf()->in_avail() and if it doesn't this might indeed be a compiler bug.

like image 130
MikeMB Avatar answered Oct 22 '22 02:10

MikeMB