Required string parser

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rushik

    #1

    Required string parser

    Hello,

    I am writing one application in which I am getting data as a string "
    10 | 20 | 30 | 40 | 50" now my aim is to parse those string, split it
    by pipe '|' and get integer outputs in some array or other data
    structure.....

    do anybody worked in the same functionality, then please let me know.

    Thanks,
    Rushik.

  • Papastefanos Serafeim

    #2
    Re: Required string parser



    ? "rushik" <rushik.upadhya y@gmail.com???? ?? ??? ??????
    news:1159953521 .521679.175770@ c28g2000cwb.goo glegroups.com.. .
    Hello,
    >
    I am writing one application in which I am getting data as a string "
    10 | 20 | 30 | 40 | 50" now my aim is to parse those string, split it
    by pipe '|' and get integer outputs in some array or other data
    structure.....
    >
    do anybody worked in the same functionality, then please let me know.
    >
    Thanks,
    Rushik.
    >
    You can use the strtok function:


    Be careful though, strtok works with char *.


    --
    Serafeim


    Comment

    • Abhishek Srivastava

      #3
      Re: Required string parser


      Papastefanos Serafeim wrote:
      ? "rushik" <rushik.upadhya y@gmail.com???? ?? ??? ??????
      news:1159953521 .521679.175770@ c28g2000cwb.goo glegroups.com.. .
      Hello,

      I am writing one application in which I am getting data as a string "
      10 | 20 | 30 | 40 | 50" now my aim is to parse those string, split it
      by pipe '|' and get integer outputs in some array or other data
      structure.....

      do anybody worked in the same functionality, then please let me know.

      Thanks,
      Rushik.
      Hi,

      Seems simple. My suggestion...

      Iterate till length of string
      {
      Iterate till '|' found
      {
      extract char at ctr and concatenate char to std::string
      increment ctr
      }
      increment ctr
      if(length of string 0)
      {
      convert temp string into number using atoi() and store in int vector
      reset std::string
      }
      }

      Convert the pseudo code into C++ :) If it is production code, then you
      will obviously put in more checks.

      Regards,
      Abhishek Srivastava

      Comment

      • Salt_Peter

        #4
        Re: Required string parser


        rushik wrote:
        Hello,
        >
        I am writing one application in which I am getting data as a string "
        10 | 20 | 30 | 40 | 50" now my aim is to parse those string, split it
        by pipe '|' and get integer outputs in some array or other data
        structure.....
        >
        do anybody worked in the same functionality, then please let me know.
        >
        Thanks,
        Rushik.
        If however you prefer doing it yourself, the std::string is well
        capable of pumping out a parser. Keep in mind that you should use
        std::string::si ze_type to hold those values returned by find_first_of
        -like member functions. You can then std::istringstr eam the substrings
        to generate the numbers. The std::string class includes a panoply of
        member functions and ctors that will let you substring at construction
        time or using assign(...), etc.

        Here is one nasty example that uses 2 functions, one to populate a
        container of relevant substrings and another templated function to
        convert the substrings into a container of numbers. It'll work with
        any seperator including spaces, comma, colon, etc or any combination of
        these. The error checking is rudimentary at best (you need to supply
        the correct seperator).

        Take note that t_track is used to prevent find_first_of from rolling up
        to std::string::np os ( a costly operation on some implementations ).
        Also, there is most likely better ways of doing this.
        check out boost's tokenizer, for example.

        #include <iostream>
        #include <ostream>
        #include <string>
        #include <vector>
        #include <sstream>
        #include <stdexcept>

        void parser( std::vector<std ::string>& r_v,
        const std::string& s,
        const std::string& r_sep )
        {
        std::string::si ze_type t_track = s.find_last_of( r_sep);
        if ( t_track == std::string::np os )
        {
        throw std::exception( ); // no sep found
        }
        std::string s_temp(s); // decapitating string
        while ( t_track != std::string::np os )
        {
        std::string::si ze_type t_size = s_temp.find_fir st_of(r_sep);
        std::string s_add(s_temp, 0, t_size);
        std::cout << "s_add = " << s_add << std::endl;
        r_v.push_back(s _add);
        t_track = t_track - s_add.size() - r_sep.size(); // npos?
        s_temp.assign(s _temp, t_size + r_sep.size(), s_temp.size());
        std::cout << "s_temp = " << s_temp << std::endl;
        }
        r_v.push_back(s _temp); // push last one
        }

        template< typename T >
        void converter( std::vector<std ::string>& r_vs,
        std::vector<T>& r_vt )
        {
        typedef std::vector<std ::string>::iter ator VIter;
        VIter iter = r_vs.begin();
        for (iter; iter != r_vs.end(); ++iter)
        {
        T t;
        std::istringstr eam iss(*iter);
        iss >t;
        r_vt.push_back( t);
        }
        }

        int main()
        {
        std::string s("10 | 20 | 30 | 40 | 50");
        // std::string s("-11 20 -3 2 4 3 1 -6");
        std::vector<std ::stringvs;

        try
        {
        parser(vs, s, " | ");
        std::vector<int vn;
        converter<int>( vs, vn);
        for (size_t i = 0; i < vn.size(); ++i)
        {
        std::cout << "vn[ " << i << "] = ";
        std::cout << vn.at(i) << std::endl;
        }
        }
        catch ( const std::exception& e )
        {
        std::cout << "Error !" << std::endl;
        }

        return 0;
        }

        /*
        s_add = 10
        s_temp = 20 | 30 | 40 | 50
        s_add = 20
        s_temp = 30 | 40 | 50
        s_add = 30
        s_temp = 40 | 50
        s_add = 40
        s_temp = 50
        vn[ 0] = 10
        vn[ 1] = 20
        vn[ 2] = 30
        vn[ 3] = 40
        vn[ 4] = 50
        */

        Comment

        • Roland Pibinger

          #5
          Re: Required string parser

          On 4 Oct 2006 09:49:27 -0700, "Salt_Peter " <pj_hern@yahoo. comwrote:
          >
          >template< typename T >
          >void converter( std::vector<std ::string>& r_vs,
          std::vector<T>& r_vt )
          >{
          typedef std::vector<std ::string>::iter ator VIter;
          VIter iter = r_vs.begin();
          for (iter; iter != r_vs.end(); ++iter)
          {
          T t;
          std::istringstr eam iss(*iter);
          iss >t;
          r_vt.push_back( t);
          }
          >}
          >
          >int main()
          >{
          std::string s("10 | 20 | 30 | 40 | 50");
          // std::string s("-11 20 -3 2 4 3 1 -6");
          std::vector<std ::stringvs;
          >
          try
          {
          parser(vs, s, " | ");
          std::vector<int vn;
          converter<int>( vs, vn);
          for (size_t i = 0; i < vn.size(); ++i)
          {
          std::cout << "vn[ " << i << "] = ";
          std::cout << vn.at(i) << std::endl;
          }
          }
          catch ( const std::exception& e )
          {
          std::cout << "Error !" std::endl;
          }
          >
          return 0;
          >}
          Your try/catch blocks seem to indicate sufficient error treatment. But
          the most problematic part of the program, the conversion between sting
          and int (with inefficient stringstream), omits any error handling.

          Best wishes,
          Roland Pibinger

          Comment

          • vheinitz

            #6
            Re: Required string parser


            rushik wrote:
            Hello,
            >
            I am writing one application in which I am getting data as a string "
            10 | 20 | 30 | 40 | 50" now my aim is to parse those string, split it
            by pipe '|' and get integer outputs in some array or other data
            structure.....
            >
            do anybody worked in the same functionality, then please let me know.
            >
            Thanks,
            Rushik.
            std::string data="10 | 20 | 30 | 40 | 50";
            std::stringstre am sstr(data); // include sstream
            int i1, i2, i3,i4,i5;
            char c;
            sstr >i1>>c>>i2>>c>> i3>>c>>i4>>c>>i 5;

            or like this
            int i;
            char c;
            std::vector<int vec;
            while(sstr.rdbu f()->in_avail())
            {
            sstr>>i>>c;
            vec.push_back(i ) ;
            }

            There are many possibilities.
            strtok and sscanf are the worst of them.

            Best Regards,
            Valentin Heinitz

            This website is for sale! heinitz-it.de is your first and best source for information about heinitz it. Here you will also find topics relating to issues of general interest. We hope you find what you are looking for!


            Comment

            • Salt_Peter

              #7
              Re: Required string parser


              Roland Pibinger wrote:
              On 4 Oct 2006 09:49:27 -0700, "Salt_Peter " <pj_hern@yahoo. comwrote:

              template< typename T >
              void converter( std::vector<std ::string>& r_vs,
              std::vector<T>& r_vt )
              {
              typedef std::vector<std ::string>::iter ator VIter;
              VIter iter = r_vs.begin();
              for (iter; iter != r_vs.end(); ++iter)
              {
              T t;
              std::istringstr eam iss(*iter);
              iss >t;
              r_vt.push_back( t);
              }
              }

              int main()
              {
              std::string s("10 | 20 | 30 | 40 | 50");
              // std::string s("-11 20 -3 2 4 3 1 -6");
              std::vector<std ::stringvs;

              try
              {
              parser(vs, s, " | ");
              std::vector<int vn;
              converter<int>( vs, vn);
              for (size_t i = 0; i < vn.size(); ++i)
              {
              std::cout << "vn[ " << i << "] = ";
              std::cout << vn.at(i) << std::endl;
              }
              }
              catch ( const std::exception& e )
              {
              std::cout << "Error !" std::endl;
              }

              return 0;
              }
              >
              Your try/catch blocks seem to indicate sufficient error treatment. But
              the most problematic part of the program, the conversion between sting
              and int (with inefficient stringstream), omits any error handling.
              >
              Best wishes,
              Roland Pibinger
              I agree. i see that a simple if_conversion_t est should provide a simple
              solution:

              [39.2] How do I convert a std::string to a number?

              int n;
              std::string s;
              std::istringstr eam iss(s);
              if ( !(i >n) ) // test
              throw std::exception( );
              ....

              Have you a better proposal insofar as the std::stringstre am is
              concerned?
              Did you mean inefficient as in the stream being regenerated over each
              loop?
              Or rdbuf() and clear() is what you had in mind?

              Comment

              • Salt_Peter

                #8
                Re: Required string parser


                Roland Pibinger wrote:
                On 4 Oct 2006 09:49:27 -0700, "Salt_Peter " <pj_hern@yahoo. comwrote:

                template< typename T >
                void converter( std::vector<std ::string>& r_vs,
                std::vector<T>& r_vt )
                {
                typedef std::vector<std ::string>::iter ator VIter;
                VIter iter = r_vs.begin();
                for (iter; iter != r_vs.end(); ++iter)
                {
                T t;
                std::istringstr eam iss(*iter);
                iss >t;
                r_vt.push_back( t);
                }
                }

                int main()
                {
                std::string s("10 | 20 | 30 | 40 | 50");
                // std::string s("-11 20 -3 2 4 3 1 -6");
                std::vector<std ::stringvs;

                try
                {
                parser(vs, s, " | ");
                std::vector<int vn;
                converter<int>( vs, vn);
                for (size_t i = 0; i < vn.size(); ++i)
                {
                std::cout << "vn[ " << i << "] = ";
                std::cout << vn.at(i) << std::endl;
                }
                }
                catch ( const std::exception& e )
                {
                std::cout << "Error !" std::endl;
                }

                return 0;
                }
                >
                Your try/catch blocks seem to indicate sufficient error treatment. But
                the most problematic part of the program, the conversion between sting
                and int (with inefficient stringstream), omits any error handling.
                >
                Best wishes,
                Roland Pibinger
                I agree. i see that a simple if_conversion_t est should provide a simple
                solution:

                [39.2] How do I convert a std::string to a number?

                int n;
                std::string s;
                std::istringstr eam iss(s);
                if ( !(iss >n) ) // test
                throw std::exception( );
                ....

                Have you a better proposal insofar as the std::stringstre am is
                concerned?
                Did you mean inefficient as in the stream being regenerated over each
                loop?
                Or rdbuf() and clear() is what you had in mind?

                Comment

                • Roland Pibinger

                  #9
                  Re: Required string parser

                  On 4 Oct 2006 19:49:56 -0700, "Salt_Peter " <...@yahoo.comw rote:
                  >i see that a simple if_conversion_t est should provide a simple
                  >solution:
                  >http://www.parashift.com/c++-faq-lit...al-issues.html
                  >[39.2] How do I convert a std::string to a number?
                  >
                  >int n;
                  >std::string s;
                  >std::istringst ream iss(s);
                  >if ( !(i >n) ) // test
                  throw std::exception( );
                  >...
                  >
                  >Have you a better proposal insofar as the std::stringstre am is
                  >concerned?
                  >Did you mean inefficient as in the stream being regenerated over each
                  >loop?
                  At least move the stringstream out of the loop. Alternatively you may
                  consider to encapsulate strtol or similar functions (but those
                  functions are a little tricky).

                  Best wishes,
                  Roland Pibinger

                  Comment

                  Working...