stringstream Problems

Discussion in 'C++' started by Mike Copeland, Apr 26, 2013.

  1. I am trying to use stringstreams to parse some complex data. In the
    code below, myTest is a string that contains int (9), char ('M'),
    string ("45-49") and
    string (" Male Age Group 45-49") data fields, and I can't get the
    code to work. Perhaps there's an option to set or function to call, but
    I'm lost here. Please advise. TIA

    stringstream sss;
    string myTest = "9 M45-49 Male Age Group 45-49 ";
    string s1, s2;
    int i1;
    char c1;
    sss.str(myTest);
    sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;
    Mike Copeland, Apr 26, 2013
    #1
    1. Advertising

  2. On 4/26/2013 5:52 PM, Mike Copeland wrote:
    > I am trying to use stringstreams to parse some complex data. In the
    > code below, myTest is a string that contains int (9), char ('M'),
    > string ("45-49") and
    > string (" Male Age Group 45-49") data fields, and I can't get the
    > code to work. Perhaps there's an option to set or function to call, but
    > I'm lost here. Please advise. TIA
    >
    > stringstream sss;
    > string myTest = "9 M45-49 Male Age Group 45-49 ";
    > string s1, s2;
    > int i1;
    > char c1;
    > sss.str(myTest);
    > sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;
    >


    You seem to be confused about when separates a token in a stream and how
    setw works.

    Every time you attempt to extract something from a stream, it will
    extract text up to the first space character it encounters, by default.
    It then _attempts_ to transform that sequence of characters into the
    type you are requesting, if an operator for it is defined. If the
    transformation fails, the fail bit will be set, you need to check for
    that on every extraction.

    if( (mystream >> myint).fail() )
    {
    // could not convert token to int
    }

    In your example above, you have 6 tokens
    You attempt to extract 4. Start with that problem.
    Christopher Pisz, Apr 27, 2013
    #2
    1. Advertising

  3. In article <klf1bg$4fe$>, says...
    > > I am trying to use stringstreams to parse some complex data. In the
    > > code below, myTest is a string that contains int (9), char ('M'),
    > > string ("45-49") and
    > > string (" Male Age Group 45-49") data fields, and I can't get the
    > > code to work. Perhaps there's an option to set or function to call, but
    > > I'm lost here. Please advise. TIA
    > >
    > > stringstream sss;
    > > string myTest = "9 M45-49 Male Age Group 45-49 ";
    > > string s1, s2;
    > > int i1;
    > > char c1;
    > > sss.str(myTest);
    > > sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;
    > >

    >
    > You seem to be confused about when separates a token in a stream and how
    > setw works.
    >
    > Every time you attempt to extract something from a stream, it will
    > extract text up to the first space character it encounters, by default.
    > It then _attempts_ to transform that sequence of characters into the
    > type you are requesting, if an operator for it is defined. If the
    > transformation fails, the fail bit will be set, you need to check for
    > that on every extraction.
    >
    > if( (mystream >> myint).fail() )
    > {
    > // could not convert token to int
    > }
    >
    > In your example above, you have 6 tokens
    > You attempt to extract 4. Start with that problem.


    Actually, you've helped. The characteristic of space-delimitation is
    a "deal-killer" for me, because what follows the 3rd token can't be
    predicted. Yes, in my example there are 6 "tokens", but I want to treat
    everything after the 4th token as a single (string) token. With these
    constructs, the stringstream technique won't work for me. 8<{{
    Thanks for the help, though...
    Mike Copeland, Apr 27, 2013
    #3
  4. On Saturday, April 27, 2013 12:52:10 AM UTC+2, Mike Copeland wrote:
    > I am trying to use stringstreams to parse some complex data. In the
    > code below, myTest is a string that contains int (9), char ('M'),
    > string ("45-49") and
    > string (" Male Age Group 45-49") data fields, and I can't get the
    > code to work. Perhaps there's an option to set or function to call, but
    > I'm lost here. Please advise. TIA
    >
    > stringstream sss;
    > string myTest = "9 M45-49 Male Age Group 45-49 ";
    > string s1, s2;
    > int i1;
    > char c1;
    > sss.str(myTest);
    > sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;


    Reading a string from an input stream is always white space
    delimited. If the only string containing white space is the
    last part of the line you can use std::getline() like this:

    std::stringstream ss("9 M45-49 Male Age Group 45-49 ");
    std::string s1, s2;
    int i1;
    char c1;

    if (ss >> i1 >> c1 >> s1 && std::getline(ss, s2))
    std::cout <<
    "(" << i1 << ")" <<
    "(" << c1 << ")" <<
    "(" << s1 << ")" <<
    "(" << s2 << ")" << "\n";

    You may want to have a look at using regex to handle more
    complex input data.
    Gert-Jan de Vos, Apr 27, 2013
    #4
  5. On Fri, 26 Apr 2013 22:38:24 -0700, Mike Copeland wrote:

    > In article <klf1bg$4fe$>, says...
    >> > I am trying to use stringstreams to parse some complex data. In
    >> > the
    >> > code below, myTest is a string that contains int (9), char ('M'),
    >> > string ("45-49") and
    >> > string (" Male Age Group 45-49") data fields, and I can't get the
    >> > code to work. Perhaps there's an option to set or function to call,
    >> > but I'm lost here. Please advise. TIA
    >> >
    >> > stringstream sss;
    >> > string myTest = "9 M45-49 Male Age Group 45-49 "; string s1,
    >> > s2;
    >> > int i1;
    >> > char c1;
    >> > sss.str(myTest);
    >> > sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;
    >> >
    >> >

    >> You seem to be confused about when separates a token in a stream and
    >> how setw works.
    >>
    >> Every time you attempt to extract something from a stream, it will
    >> extract text up to the first space character it encounters, by default.
    >> It then _attempts_ to transform that sequence of characters into the
    >> type you are requesting, if an operator for it is defined.


    That is not true. Conceptually, the stream extraction operators (>>) read
    *one* character ahead to see if that could still be be part of the type
    you are trying to read. In this process, leading whitespace before a
    value are always considered acceptable and are silently discarded.
    operator>>(istream, string) is a bit special, because it considers a
    whitespace character (other than the leading whitespace) to be
    inappropriate for storing in a string.

    Combined, this results in the apparent behaviour that values should be
    separated by spaces (which is only strictly needed for values of
    sufficiently similar types) and that only single words can be read into a
    string.

    >> If the
    >> transformation fails, the fail bit will be set, you need to check for
    >> that on every extraction.
    >>
    >> if( (mystream >> myint).fail() )
    >> {
    >> // could not convert token to int
    >> }
    >>
    >> In your example above, you have 6 tokens You attempt to extract 4.
    >> Start with that problem.

    >
    > Actually, you've helped. The characteristic of space-delimitation is
    > a "deal-killer" for me, because what follows the 3rd token can't be
    > predicted. Yes, in my example there are 6 "tokens", but I want to treat
    > everything after the 4th token as a single (string) token. With these
    > constructs, the stringstream technique won't work for me. 8<{{
    > Thanks for the help, though...


    As most of the spaces in your example string are in the right positions,
    you can parse it with a combination of operator>> and getline:

    stringstream sss;
    string myTest = "9 M45-49 Male Age Group 45-49 ";
    string s1, s2;
    int i1;
    char c1;
    sss.str(myTest);
    sss >> i1 >> c1 >> s1;
    getline(sss, s2);

    Bart v Ingen Schenau
    Bart van Ingen Schenau, Apr 29, 2013
    #5
  6. On 4/27/2013 12:38 AM, Mike Copeland wrote:
    > In article <klf1bg$4fe$>, says...
    >>> I am trying to use stringstreams to parse some complex data. In the
    >>> code below, myTest is a string that contains int (9), char ('M'),
    >>> string ("45-49") and
    >>> string (" Male Age Group 45-49") data fields, and I can't get the
    >>> code to work. Perhaps there's an option to set or function to call, but
    >>> I'm lost here. Please advise. TIA
    >>>
    >>> stringstream sss;
    >>> string myTest = "9 M45-49 Male Age Group 45-49 ";
    >>> string s1, s2;
    >>> int i1;
    >>> char c1;
    >>> sss.str(myTest);
    >>> sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;
    >>>

    >>
    >> You seem to be confused about when separates a token in a stream and how
    >> setw works.
    >>
    >> Every time you attempt to extract something from a stream, it will
    >> extract text up to the first space character it encounters, by default.
    >> It then _attempts_ to transform that sequence of characters into the
    >> type you are requesting, if an operator for it is defined. If the
    >> transformation fails, the fail bit will be set, you need to check for
    >> that on every extraction.
    >>
    >> if( (mystream >> myint).fail() )
    >> {
    >> // could not convert token to int
    >> }
    >>
    >> In your example above, you have 6 tokens
    >> You attempt to extract 4. Start with that problem.

    >
    > Actually, you've helped. The characteristic of space-delimitation is
    > a "deal-killer" for me, because what follows the 3rd token can't be
    > predicted. Yes, in my example there are 6 "tokens", but I want to treat
    > everything after the 4th token as a single (string) token. With these
    > constructs, the stringstream technique won't work for me. 8<{{
    > Thanks for the help, though...


    Well, stringstream cannot be psychic. Something has to signify the
    separation. Since the same character that defines the separation is part
    of the data, you need to use a different character to define the
    separation. Say, a comma for example. Then use istream::getline with the
    delimiter argument.

    You could also use the gcount, peek, read, seekg, etc. methods if you
    wanted to define some protocol where each field has a specified number
    of characters, but you will have to put them in that way too.
    Christopher Pisz, Apr 29, 2013
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marc Schellens

    stringstream

    Marc Schellens, Jul 1, 2003, in forum: C++
    Replies:
    3
    Views:
    521
  2. minjie
    Replies:
    1
    Views:
    646
    Victor Bazarov
    Jul 15, 2003
  3. Bill Beacom

    stringstream problem

    Bill Beacom, Sep 15, 2003, in forum: C++
    Replies:
    2
    Views:
    458
    Peter Kragh
    Sep 15, 2003
  4. Ellarco
    Replies:
    5
    Views:
    4,508
    Ellarco
    Sep 24, 2003
  5. Nick Keighley

    stringstream problems

    Nick Keighley, May 16, 2010, in forum: C++
    Replies:
    7
    Views:
    1,707
    Nick Keighley
    May 27, 2010
Loading...

Share This Page