istringstream

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • k:arel

    #1

    istringstream

    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<<",s pacer="<<spacer <<",seed="<<see d<<endl;
    /* *************** *************** *************** ** */

    yet, when i run this, the output is:
    msgcode=1,space r=@+@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?

  • roberts.noah@gmail.com

    #2
    Re: istringstream


    k:arel wrote:
    [color=blue]
    > /* *************** *************** *************** ** */
    > istringstream in;
    > in.str("1@+@5") ;[/color]
    [color=blue]
    > in >> msgcode >> spacer >> seed;[/color]
    [color=blue]
    > 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...[/color]

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

    Comment

    • red floyd

      #3
      Re: istringstream

      k:arel wrote:[color=blue]
      > 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<<",s pacer="<<spacer <<",seed="<<see d<<endl;
      > /* *************** *************** *************** ** */
      >
      > yet, when i run this, the output is:
      > msgcode=1,space r=@+@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...
      >[/color]

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

      See this thread for details:

      Comment

      • red floyd

        #4
        Re: istringstream

        roberts.noah@gm ail.com wrote:[color=blue]
        > k:arel wrote:
        >[color=green]
        >> /* *************** *************** *************** ** */
        >> istringstream in;
        >> in.str("1@+@5") ;[/color]
        >[color=green]
        >> in >> msgcode >> spacer >> seed;[/color]
        >[color=green]
        >> 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...[/color]
        >
        > Reading a string gobbles up everything up to any whitespace. I don't
        > think it will be the best answer to your problem.
        >[/color]

        Ah, good point, I missed that. However, there is also an issue with VS2005.

        Comment

        • red floyd

          #5
          Re: istringstream

          red floyd wrote:[color=blue]
          > k:arel wrote:[color=green]
          >> 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<<",s pacer="<<spacer <<",seed="<<see d<<endl;
          >> /* *************** *************** *************** ** */
          >>
          >> yet, when i run this, the output is:
          >> msgcode=1,space r=@+@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...
          >>[/color]
          >
          > If you're using VS 2005, this is a known bug in the library.
          >
          > See this thread for details:
          > http://groups.google.com/group/micro...d09bf204?tvc=1
          >[/color]

          Ignore this. Noah had the correct answer.

          Comment

          • Nitin Motgi

            #6
            Re: istringstream

            roberts.noah@gm ail.com wrote:[color=blue]
            > k:arel wrote:
            >[color=green]
            > > /* *************** *************** *************** ** */
            > > istringstream in;
            > > in.str("1@+@5") ;[/color]
            >[color=green]
            > > in >> msgcode >> spacer >> seed;[/color]
            >[color=green]
            > > 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...[/color]
            >
            > Reading a string gobbles up everything up to any whitespace. I don't
            > think it will be the best answer to your problem.[/color]

            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.

            Comment

            • BobR

              #7
              Re: istringstream


              roberts.noah@gm ail.com wrote in message ...[color=blue]
              >
              >k:arel wrote:[color=green]
              >> /* *************** *************** *************** ** */
              >> istringstream in;
              >> in.str("1@+@5") ;
              >> in >> msgcode >> spacer >> seed;[/color]
              >[color=green]
              >> 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...[/color]
              >
              >Reading a string gobbles up everything up to any whitespace. I don't
              >think it will be the best answer to your problem.[/color]

              k:arel,

              Try 'getline()' with a delimiter:

              {
              std::istringstr eam 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="<<th estring
              <<" num2="<<num2<<s td::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


              Comment

              • k:arel

                #8
                Re: istringstream

                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(i n, separator);
                in >> seed;


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

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


                thanks for the replies!

                Comment

                • k:arel

                  #9
                  Re: istringstream

                  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...

                  Comment

                  • Ben Pope

                    #10
                    Re: istringstream

                    k:arel wrote:[color=blue]
                    > 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...[/color]

                    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...

                    Comment

                    • Nitin Motgi

                      #11
                      Re: istringstream

                      k:arel wrote:[color=blue]
                      > ok, this did the trick:
                      >[/color]
                      [color=blue]
                      > char ch;
                      > in >> msgcode >> ch>>ch>>ch>> seed;[/color]

                      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.
                      [color=blue]
                      > though you could (!) solve it like this:
                      > /* *************** *************** *************** ** */
                      > istringstream in;
                      > in.str("1@+@55" );
                      >
                      > int msgcode=-1;
                      > int seed=-1;
                      > in >> msgcode;
                      > readSeparator(i n, separator);
                      > in >> seed;
                      >[/color]

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

                      Thank you
                      Nitin Motgi

                      Comment

                      Working...