0

so I made a function to parse a given string with a comma delimiter last semester during a haze. Its very likely I took much of it from guides online, but it worked for the overall project so I did it. Now i'm going back and reviewing it, and i'm confused. Here is the code

`vector parsedString(string line){ vector splitStrings;

stringstream inputString(line);

    while(inputString.good()){
        string substr;
        getline(inputString,substr,',');
        splitStrings.push_back(substr);
                
        substr = "";
        }

return splitStrings;
    

}`

The purpose was to put each part of the line thats seperated into a vector, then take that vector back where its needed with all the parts. However, I do NOT understand the stringstream aspects of this.

To be specific, when I wrote code to check stringstreams contents during the loop, it stayed the same for the entire time. If getline() is supposed to track where the last delimiter was, why does it not show in the contents?

also if possible, an explanation on how .good() works in this case would be phenomenal. I understand stringstream is a stream, and function of that sort are supposed to check if streams are finished or not, but again I don't understand how the program would know that.

Everything works as intended, there is no mistakes being made from what I can see. I just fundamentally can't seem to grasp why its working, and I don't want my lack of knowledge to come back to bite me.

  • `If getline() is supposed to track where the last delimiter was, why does it not show in the contents?` it doesn't, your stream tracks it. Why do you think the content of stringstream should change though? It probably just remembers the offset. Also: https://en.cppreference.com/w/cpp/io/basic_ios/good – tkausl Jan 22 '23 at 19:47
  • This code is flawed. If `getline(inputString,substr,',');` fails you'll use that data before checking the stream state again. A better loop is `while (getline(inputString,substr,',')) { splitStrings.push_back(substr); }` – Retired Ninja Jan 22 '23 at 19:54
  • Same concept as [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) which is check for the condition you care about, not the one you don't. – Retired Ninja Jan 22 '23 at 19:55

1 Answers1

0

A istringstream is not just a string. If it were, it would be redundant.

For a first approximation, you could think of it as a class whose instances contain a string and a position (i.e., a string index). When you construct the istringstream from a string, the position is initialised to 0. When you read a character from the istringstream, you get the character at the position, and the position is incremented. So each time you read a character, you get the next one. (Actually, a stringstream has two positions, one for reading and one for writing, because it's a combination of an istringstream and an ostreamstring. But only the input part is relevant to your question.)

All other stream input operations are based on reading a single character, although implementations are allowed to be more efficient if the results are the same.

The above was an oversimplification, of course. A stream has other state: status bits, formatting parameters, locale settings, and more stuff I'm forgetting. See this overview for more details. But the basic point stands: the string is only a part of a stringstream's state: the rest of the state is used to make it look like an I/O stream. Which turns out to be useful if you want to pick it apart sequentially into tokens.

rici
  • 234,347
  • 28
  • 237
  • 341