5

I am learning C++ at the moment and am working to understand streams. Today I learned this really cool thing, you can split a string stream into multiple floats/integers, like:

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    stringstream ss("1 2.2");
    int val1; float val2;
    ss >> val1 >> val2;
    cout << "val1: " << val1 << endl
         << "val2: " << val2;
    return 0;
}

Now a problem arises when instead of "1 2.2" as an input string I use "1,2.2", which is similar to what I would get from a csv file. I would like to be able to write something that would take such a csv string and transform it into the same type of stream as in the example above. I imagine it would look something like

ss >> mySpecialPipe >> val1 >> val2;

Now I know mySpecialPipe should do a few things:

  1. Take in the input
  2. Split the input
  3. Write the input when requested

So I tried to build this:

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

using namespace std;

class MySpecialPipe {
    private:
        char delimiter;
    public:
        vector<string> buffer;
        MySpecialPipe(char delimeter);
        friend istream& operator>> (istream &in, MySpecialPipe &p);
        friend istream& operator>> (MySpecialPipe &p, istream &in);
};

MySpecialPipe::MySpecialPipe(char delimeter): delimiter(delimeter) {}

istream& operator>> (istream &in,  MySpecialPipe &p)
{
    string s;
    while (getline(in, s, p.delimiter)) {
        p.buffer.push_back(s);
    }

    return in;
}

istream& operator>> (MySpecialPipe &p, istream &in) {
    for (string s: p.buffer) {
        // s >> in;
    }
    p.buffer.clear();
    return in;
}

int main() {
    MySpecialPipe p = MySpecialPipe(',');
    stringstream ss("1,2.2");
    stringstream ss2;
    ss >> p >> val1 >> val2;
}

As you can see I have uncommented the line s >> in, because the compiler complains, but essentially that is what I want to do. Is this even possible?

If you got here, thank you for your time, I look forward to your answers.

  • `s >> in;` looks like you want to put the contents of `s` into input stream `in`. What I think you really want to do is go deeper and hide the pipe inside its own input stream so you can read out of it like it's a stream. But I'm not 100% sure. Could you please clarify? – user4581301 Nov 13 '20 at 21:39
  • Hiding the pipe in it's own input stream sounds really cool and possibly like what I am looking for! – Robin Dorstijn Nov 13 '20 at 21:47
  • Basically I just want to be able to stream a comma separated string into variables like a space separated one can be (e.g. first example). – Robin Dorstijn Nov 13 '20 at 21:48
  • 1
    You can read some of the answers to [this question](https://stackoverflow.com/q/1120140/315052) to get some ideas. But, I think your question is heavily overlapped with [this question](https://stackoverflow.com/q/7302996/315052). – jxh Nov 13 '20 at 22:32
  • 1
    suggest you take a look at [this](https://stackoverflow.com/questions/7302996/changing-the-delimiter-for-cin-c) and [this](https://stackoverflow.com/questions/50154766/how-to-include-c-input-stream-delimiters-into-result-tokens) – GreatAndPowerfulOz Nov 14 '20 at 05:20
  • Changing the delimiter is probably the right "XY problem" answer. But if you're interested in making streams that transform data, you can check out [this article](http://gabisoft.free.fr/articles/fltrsbf1.html), as well as this [repo](https://github.com/allebacco/compressed_streams) which implements compression/decompression streams. – parktomatomi Nov 14 '20 at 08:12

0 Answers0