Search code examples
c++c++11c++14stringstream

istringstream put string back on input and read again


So i read out lines out of a file and then read out the lines via stringstream.

I found the Issue that because of the format of the line rarely 2 seperate parts are written together and get read together as one string. I tryed to fix that situation by putting the wrong read value back on the stream and read again but it looks like istringstream doesnt care i put the chars back. they simply dont get read out again.

Here the Problem broken down. S1 is a good string. S2 adresses the Issue with the wrong read in the comments:

In short. Is it possible to put a string back on istringstream and read it with the next operation??

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


int main()
{
    std::string device_id;              //126, I_VS_MainVoltageAvailabl
    std::string ea_type;                //E
    std::string address;                //0.1
    std::string data_type;              //BOOL
    std::vector<std::string> comment;   //VS - Steuerspannung vorhanden / Main voltage available"

    std::string s1 = "126,I_Btn_function_stop     E       1.2 BOOL      Taster Stopp Funktion / Button Stop Function";
    std::string s2 = "126,I_VS_MainVoltageAvailablE       0.1 BOOL      VS - Steuerspannung vorhanden / Main voltage available";

    std::istringstream ist{ s2 };
    ist >> device_id;                   // Read 126, I_VS_MainVoltageAvailablE    the E should be read in ea_type
    ist >> ea_type;                     // 0.1

    //my idea
    if (!ea_type.empty() && isdigit(static_cast<unsigned char>(ea_type[0]))) {  //first is a digit so already next was read

        for (const auto& x : ea_type)       //Try to put 0.1 in the stream
            ist.putback(x);

        ea_type = device_id[device_id.size() - 1];      // = "E"
        device_id.pop_back();                           // = "126, I_VS_MainVoltageAvailabl"
    }
    ist >> address;                                     // Expected "0.1" instead  "BOOL" why 0.1 was putback on the stream???
    ist >> data_type;

    for (std::string in; ist >> in;)
        comment.push_back(in);
}

Solution

  • As usual, people are ignoring return codes. putback has a return code for a reason, and when it is false, it means putback failed.

    In particular, std::istringstream is input string stream, and as such, is input-only stream. Because of that, you can't use putback on it, it will always fail.

    However, you can use std::stringstream instead, and with that putback will behave the way you want it to.