istringstream

Discussion in 'C++' started by k:arel, Jan 30, 2006.

  1. k:arel

    k:arel Guest

    today i've discovered the istringstream object
    i'm trying to read a string and split it up in a number of fields,
    consisting of integers and strings

    it's for a protocol that sends messages with:
    * message code, pe. 1 for HELLO
    * message content, pe. 5 (seed)

    both field are separated by @+@

    /* *********************************************** */
    istringstream in;
    in.str("1@+@5");

    int msgcode=-1;
    int seed=-1;
    string spacer;

    in >> msgcode >> spacer >> seed;

    cout<<"msgcode="<<msgcode<<",spacer="<<spacer<<",seed="<<seed<<endl;
    /* *********************************************** */

    yet, when i run this, the output is:
    msgcode=1,spacer=@+@5,seed=-1

    the 5 always belongs to the string "spacer"

    also replacing the @+@ by a space or taking a char* as data type for
    "spacer" doesn't put the 5 in the "seed"
    the string "spacer" alway reaches to the end (also if we set there 555
    instead of just 5), it's probably because the stream can't tell where
    to end the string and start the integer...

    has anybody any idea how i could bypass this?
     
    k:arel, Jan 30, 2006
    #1
    1. Advertising

  2. k:arel

    Guest

    k:arel wrote:

    > /* *********************************************** */
    > istringstream in;
    > in.str("1@+@5");


    > in >> msgcode >> spacer >> seed;


    > the string "spacer" alway reaches to the end (also if we set there 555
    > instead of just 5), it's probably because the stream can't tell where
    > to end the string and start the integer...


    Reading a string gobbles up everything up to any whitespace. I don't
    think it will be the best answer to your problem.
     
    , Jan 30, 2006
    #2
    1. Advertising

  3. k:arel

    red floyd Guest

    k:arel wrote:
    > today i've discovered the istringstream object
    > i'm trying to read a string and split it up in a number of fields,
    > consisting of integers and strings
    >
    > it's for a protocol that sends messages with:
    > * message code, pe. 1 for HELLO
    > * message content, pe. 5 (seed)
    >
    > both field are separated by @+@
    >
    > /* *********************************************** */
    > istringstream in;
    > in.str("1@+@5");
    >
    > int msgcode=-1;
    > int seed=-1;
    > string spacer;
    >
    > in >> msgcode >> spacer >> seed;
    >
    > cout<<"msgcode="<<msgcode<<",spacer="<<spacer<<",seed="<<seed<<endl;
    > /* *********************************************** */
    >
    > yet, when i run this, the output is:
    > msgcode=1,spacer=@+@5,seed=-1
    >
    > the 5 always belongs to the string "spacer"
    >
    > also replacing the @+@ by a space or taking a char* as data type for
    > "spacer" doesn't put the 5 in the "seed"
    > the string "spacer" alway reaches to the end (also if we set there 555
    > instead of just 5), it's probably because the stream can't tell where
    > to end the string and start the integer...
    >


    If you're using VS 2005, this is a known bug in the library.

    See this thread for details:
    http://groups.google.com/group/micr...hread/64ac882a37ddb1e9/eee6c084d09bf204?tvc=1
     
    red floyd, Jan 30, 2006
    #3
  4. k:arel

    red floyd Guest

    wrote:
    > k:arel wrote:
    >
    >> /* *********************************************** */
    >> istringstream in;
    >> in.str("1@+@5");

    >
    >> in >> msgcode >> spacer >> seed;

    >
    >> the string "spacer" alway reaches to the end (also if we set there 555
    >> instead of just 5), it's probably because the stream can't tell where
    >> to end the string and start the integer...

    >
    > Reading a string gobbles up everything up to any whitespace. I don't
    > think it will be the best answer to your problem.
    >


    Ah, good point, I missed that. However, there is also an issue with VS2005.
     
    red floyd, Jan 30, 2006
    #4
  5. k:arel

    red floyd Guest

    red floyd wrote:
    > k:arel wrote:
    >> today i've discovered the istringstream object
    >> i'm trying to read a string and split it up in a number of fields,
    >> consisting of integers and strings
    >>
    >> it's for a protocol that sends messages with:
    >> * message code, pe. 1 for HELLO
    >> * message content, pe. 5 (seed)
    >>
    >> both field are separated by @+@
    >>
    >> /* *********************************************** */
    >> istringstream in;
    >> in.str("1@+@5");
    >>
    >> int msgcode=-1;
    >> int seed=-1;
    >> string spacer;
    >>
    >> in >> msgcode >> spacer >> seed;
    >>
    >> cout<<"msgcode="<<msgcode<<",spacer="<<spacer<<",seed="<<seed<<endl;
    >> /* *********************************************** */
    >>
    >> yet, when i run this, the output is:
    >> msgcode=1,spacer=@+@5,seed=-1
    >>
    >> the 5 always belongs to the string "spacer"
    >>
    >> also replacing the @+@ by a space or taking a char* as data type for
    >> "spacer" doesn't put the 5 in the "seed"
    >> the string "spacer" alway reaches to the end (also if we set there 555
    >> instead of just 5), it's probably because the stream can't tell where
    >> to end the string and start the integer...
    >>

    >
    > If you're using VS 2005, this is a known bug in the library.
    >
    > See this thread for details:
    > http://groups.google.com/group/micr...hread/64ac882a37ddb1e9/eee6c084d09bf204?tvc=1
    >


    Ignore this. Noah had the correct answer.
     
    red floyd, Jan 30, 2006
    #5
  6. k:arel

    Nitin Motgi Guest

    wrote:
    > k:arel wrote:
    >
    > > /* *********************************************** */
    > > istringstream in;
    > > in.str("1@+@5");

    >
    > > in >> msgcode >> spacer >> seed;

    >
    > > the string "spacer" alway reaches to the end (also if we set there 555
    > > instead of just 5), it's probably because the stream can't tell where
    > > to end the string and start the integer...

    >
    > Reading a string gobbles up everything up to any whitespace. I don't
    > think it will be the best answer to your problem.


    Noah is right reading string messes you up. Addition of "@+@", is it
    required by the protocol or is it something that you have added as a
    seperator. If protocol does not require that then you add a seperator
    like "+ " (replace @ with space on ight hand side of +). By this when
    reading string the stream will stop after getting a space.

    -- Nitin Motgi.
     
    Nitin Motgi, Jan 30, 2006
    #6
  7. k:arel

    BobR Guest

    wrote in message ...
    >
    >k:arel wrote:
    >> /* *********************************************** */
    >> istringstream in;
    >> in.str("1@+@5");
    >> in >> msgcode >> spacer >> seed;

    >
    >> the string "spacer" alway reaches to the end (also if we set there 555
    >> instead of just 5), it's probably because the stream can't tell where
    >> to end the string and start the integer...

    >
    >Reading a string gobbles up everything up to any whitespace. I don't
    >think it will be the best answer to your problem.


    k:arel,

    Try 'getline()' with a delimiter:

    {
    std::istringstream isin("25 This is a string\n 09 1876");
    int num1(0), num2(0);
    std::string thestring;
    isin >> num1;
    isin.ignore(1); // skip the space
    std::getline( isin, thestring, '\n' );
    isin >> num2; // leading space ignored
    std::cout <<"num1="<<num1<<" thestring="<<thestring
    <<" num2="<<num2<<std::endl;
    // out: num1=25 thestring=This is a string num2=9
    }

    That help you k:arel?
    Thanks for the use of your post, Mr. roberts. <G>
    --
    Bob R
    POVrookie
     
    BobR, Jan 31, 2006
    #7
  8. k:arel

    k:arel Guest

    ok, this did the trick:

    i'm free to choose the seperator, but since where sending bash
    commands, the seperator should be "weird".

    i replaced the spaces bij underscores, so it's clearer:
    this works: in.str("1+_5");
    this works: in.str("1+_+5");
    this works: in.str("1@+@_5");
    ! mention the spaces !

    @red floyd, i'm using KDevelop3 for programming C++ because i'm using
    Unix resources in my program.

    i also found this solution:
    /* *********************************************** */
    istringstream in;
    in.str("1@+@55");

    int msgcode=-1;
    int seed=-1;
    char ch;
    in >> msgcode >> ch>>ch>>ch>> seed;
    /* *********************************************** */

    yet this solution is NOT user friendly: we won't be able to change the
    separator in a normal way then...

    though you could (!) solve it like this:
    /* *********************************************** */
    istringstream in;
    in.str("1@+@55");

    int msgcode=-1;
    int seed=-1;
    in >> msgcode;
    readSeparator(in, separator);
    in >> seed;


    void readSeparator(istringstream &in, string separator) {
    char ch;

    for(int i=0; i<separator.size() ; i++) {
    in >> ch;
    }
    }
    /* *********************************************** */


    thanks for the replies!
     
    k:arel, Jan 31, 2006
    #8
  9. k:arel

    k:arel Guest

    Bob,
    your method works fine if the separator is only one character.

    My separator is 3 characters: @+@.
    As i said before, i'm free to choose any separator, but i must be able
    to separate the fields in an obvious way.
    I could replace my separator @+@ with an other character, not used.
    But this character has to be chosen at first and it's difficult to say
    which character is NOT going to be used in any of the commands.
    Of the separator @+@, you could say, with a certain certitude, that it
    will never be send...
     
    k:arel, Jan 31, 2006
    #9
  10. k:arel

    Ben Pope Guest

    k:arel wrote:
    > Bob,
    > your method works fine if the separator is only one character.
    >
    > My separator is 3 characters: @+@.
    > As i said before, i'm free to choose any separator, but i must be able
    > to separate the fields in an obvious way.
    > I could replace my separator @+@ with an other character, not used.
    > But this character has to be chosen at first and it's difficult to say
    > which character is NOT going to be used in any of the commands.
    > Of the separator @+@, you could say, with a certain certitude, that it
    > will never be send...


    Well then do it properly. Pick an escape character.

    Take for example, C strings if you want to have a string containing a
    '\' you type it twice "\\". Now, if you see a single instance of that
    character, the next character is special. If you see it twice, you want
    the original character.

    Pick a separator that is, say '@'.

    So if your original message contains 2 fields, that are delimiter
    separated and the fields are "field1", "fi@ld2", then the encoded
    message is "field1@fi@@ld2".

    You'll have to use '@' as the delimiter and then if the next field
    starts with a @, you have to concatenate it to the current field.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Jan 31, 2006
    #10
  11. k:arel

    Nitin Motgi Guest

    k:arel wrote:
    > ok, this did the trick:
    >


    > char ch;
    > in >> msgcode >> ch>>ch>>ch>> seed;


    If the sstream has in.str("1@+@[num]") num is either a
    1,2,3, or n digit number. Then you would have to know
    in advance how many will be there.

    > though you could (!) solve it like this:
    > /* *********************************************** */
    > istringstream in;
    > in.str("1@+@55");
    >
    > int msgcode=-1;
    > int seed=-1;
    > in >> msgcode;
    > readSeparator(in, separator);
    > in >> seed;
    >


    Why don't you take a look at Boost.Tokenizer.

    Thank you
    Nitin Motgi
     
    Nitin Motgi, Jan 31, 2006
    #11
    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. Samuele Armondi

    Allocating istringstream objects

    Samuele Armondi, Jul 11, 2003, in forum: C++
    Replies:
    1
    Views:
    383
    Samuele Armondi
    Jul 11, 2003
  2. Agent Mulder

    istringstream to bool

    Agent Mulder, Aug 23, 2003, in forum: C++
    Replies:
    8
    Views:
    1,065
    Agent Mulder
    Aug 24, 2003
  3. Viet Le Hong

    istringstream question

    Viet Le Hong, Sep 18, 2003, in forum: C++
    Replies:
    3
    Views:
    702
    Buster Copley
    Sep 18, 2003
  4. bml

    istringstream???

    bml, Jan 27, 2004, in forum: C++
    Replies:
    3
    Views:
    1,083
    Karl Heinz Buchegger
    Jan 27, 2004
  5. Donald Canton

    istringstream syntax error question

    Donald Canton, Jan 29, 2004, in forum: C++
    Replies:
    1
    Views:
    419
    David Harmon
    Jan 30, 2004
Loading...

Share This Page