Max Max - 26 days ago 7
C++ Question

stringstream only works for one line then breaks when reused

I am trying to read in a simple file (simplified below) named

trajectory.txt
that looks like this:

true true false
2


My code is simple, read in and store the the first two lines in some variables.

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

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

int num_waypoints=0;
bool pos=1, vel=0, acc=0;
std::ifstream file;
std::string filename = "trajectory.txt";
file.open(filename.c_str());
std::string line;

// Read first 2 lines
if (std::getline(file, line)) {

//sstream for each line
std::stringstream ss(line);

//first line
std::string pos_str, vel_str, acc_str;
ss >> pos_str >> vel_str >> acc_str;

//evaluate
(pos_str == "true" ? pos = true : pos = false);
(vel_str == "true" ? vel = true : vel = false);
(acc_str == "true" ? acc = true : acc = false);

//second line
if (std::getline(file, line)) { //GDB confirms, line == "2"
std::string num_waypoints_str;
ss >> num_waypoints_str; //THIS DOES NOTHING?
num_waypoints = stoi(num_waypoints_str);
}

} //main()


The problem is that on the second to last line,
num_waypoints_str
is left empty after the stringstream is supposed to read in the values.

Using GDB I was able to confirm that the stringstream did infact take on the value of "2" but it seems to be having a problem directing the value to num_waypoints_str.

I therefore only have two questions:


  1. Why would the stringstream not pass its value to the string? (Does it have to do with being within a new scope)

  2. Can my code be simplified to input line 1 directly from the stringstream to the boolean
    pos
    or must I convert from string
    pos_str
    to
    pos
    by evaluating the string's value.



I am compiling via
g++ -g -std=c++11 main.cpp -o main
. Please try to duplicate my issue. I feel I am missing something simple.

Answer Source

The stringstream is not magically bound to your std::string line;:

   //second line
   if (std::getline(file, line)) {               //GDB confirms, line == "2"
     std::string num_waypoints_str;              
     ss >> num_waypoints_str;                    //THIS DOES NOTHING?
     num_waypoints = stoi(num_waypoints_str);

ss still has its value that was set up in the constructor much ahead of this. To be more precise:

The constructor of std::stringstream makes a copy of the string you give it, it does not bind to it.

You can update the content of ss by using std::basic_stringstream::str if you donĀ“t want to construct another one. Note: Like the other streams stringstreams have flags, like eof for example, those need to be reset too. So in your case its:

    ss.clear();
    ss.str(line);