Stream from a String Instead of CIN in C++
1 min read

Stream from a String Instead of CIN in C++

Stream from a String Instead of CIN in C++

TL;DR: You can stream from a string instead of STDIN. Code is simple and is listed below.

A project I did recently had a requirement to overload the >> operator use and STDIN to load data. The problem was not the overload itself, but the fact that testing would introduce a manual side. To get around that, I needed a way to stream data from a string instead of STDIN.

The solution is presented below:

#ifndef POLYMORPH_MEMSTREAM_H
#define POLYMORPH_MEMSTREAM_H

#include <streambuf>
#include <istream>

struct membuf : std::streambuf {
    membuf(char const *base, size_t size) {
        char *p(const_cast<char *>(base));
        this->setg(p, p, p + size);
    }
};

/**
  * Usage:
  *   imemstream in(data, size);
  *   in >> value;
  */
struct imemstream : virtual membuf, std::istream {
    imemstream(char const *base, size_t size)
            : membuf(base, size), std::istream(static_cast<std::streambuf *>(this)) {
    }
};

To use it, all you need to do is:

  1. Create a string:

    const char * str = "1.0\n2.0\n3.0\n4.0\n5.0\n6.0\n7.0\n8.0\n9.0\n10.0"
    

    It is notable the stream will be read in the same fashion as STDIN, with "\n" as delimiter :)

  2. Create your stream:

    imemstream in(str, strlen(str));
    
  3. Load the stream:

    for (int i = 0; i < count; i++) {
        in >> object;
    }
    

count can be strlen(str) but can also be a smaller value (in this case, it only means not all values will be loaded in your object).