Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Obtaining start position of istringstream token

Is there a way to find the start position of tokens extracted by istringstream::operator >>?

For example, my current failed attempt at checking tellg() (run online):

string test = "   first     \"  in \\\"quotes \"  last";
istringstream strm(test);

while (!strm.eof()) {

    string token;
    auto startpos = strm.tellg();
    strm >> quoted(token);
    auto endpos = strm.tellg();
    if (endpos == -1) endpos = test.length();

    cout << token << ": " << startpos << " " << endpos << endl;

}

So the output of the above program is:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

first: 0 8
  in "quotes : 8 29
last: 29 35

The end positions are fine, but the start positions are the start of the whitespace leading up to the token. The output I want would be something like:

first: 3 8
  in "quotes : 13 29
last: 31 35

Here’s the test string with positions for reference:

          1111111111222222222233333
01234567890123456789012345678901234  the end is -1

   first     "  in \"quotes "  last

        ^--------------------^-----^ the end positions i get and want
^-------^--------------------^------ the start positions i get
   ^---------^-----------------^---- the start positions i *want*

Is there any straightforward way to retrieve this information when using an istringstream?

>Solution :

First, see Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?

Second, you can use the std::ws stream manipulator to swallow whitespace before reading the next token value, then tellg() will report the start positions you are looking for, eg:

#include <string>
#include <sstream>
#include <iomanip>
using namespace std;

...

string test = "   first     \"  in \\\"quotes \"  last";
istringstream strm(test);

while (strm >> ws) {

    string token;
    auto startpos = strm.tellg();
    if (!(strm >> quoted(token)) break;
    auto endpos = strm.tellg();
    if (endpos == -1) endpos = test.length();

    cout << token << ": " << startpos << " " << endpos << endl;
}

Online Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading