Not-equal string searching

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

    Not-equal string searching

    Hello,

    Is the function below the simplest way to produce an iterator to the next
    non-space in a string? (Or the upper-bound iterator if none is found).
    Searching for a sequence is overkill and inefficient IMO.

    #include <string>
    #include <algorithm>
    #include <functional>

    std::string::it erator find_not_space( std::string &s)
    {
    char chSpace = ' ';
    return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
    std::not_equal_ to<char>());
    }



  • Daniel T.

    #2
    Re: Not-equal string searching

    "DavidW" <no@email.provi dedwrote:
    Is the function below the simplest way to produce an iterator to the next
    non-space in a string?
    No.
    std::string::it erator find_not_space( std::string &s)
    {
    char chSpace = ' ';
    return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
    std::not_equal_ to<char>());
    }
    If you aren't using boost's lambda library then:

    std::string::it erator find_not_space( std::string &s)
    {
    return find_if( s.begin(), s.end(),
    bind2nd( not_equal_to<ch ar>(), ' ' ) );
    }

    If you are using boost's lambda library:

    std::string::it erator find_not_space( std::string &s)
    {
    return find_if( s.begin(), s.end(), _1 != ' ' );
    }

    Comment

    • Kai-Uwe Bux

      #3
      Re: Not-equal string searching

      DavidW wrote:
      Hello,
      >
      Is the function below the simplest way to produce an iterator to the next
      non-space in a string? (Or the upper-bound iterator if none is found).
      Searching for a sequence is overkill and inefficient IMO.
      >
      #include <string>
      #include <algorithm>
      #include <functional>
      >
      std::string::it erator find_not_space( std::string &s)
      {
      char chSpace = ' ';
      return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
      std::not_equal_ to<char>());
      }
      a) You could use std::find_if with not_equal_to ' ' as the predicate. There
      ought to be a way to fiddle around with binders to get it into a single
      line. Or using lambda:

      find_if( s.begin(), s.end(), _1 != ' ' );


      b) Also notice the member function find_first_not_ of of std::string. It
      almost does what you want, except that it returns the index of the element
      and not an iterator.



      Best

      Kai-Uwe Bux

      Comment

      • James Kanze

        #4
        Re: Not-equal string searching

        On Feb 9, 11:39 pm, "DavidW" <n...@email.pro videdwrote:
        Is the function below the simplest way to produce an iterator to the next
        non-space in a string? (Or the upper-bound iterator if none is found).
        Searching for a sequence is overkill and inefficient IMO.
        #include <string>
        #include <algorithm>
        #include <functional>
        std::string::it erator find_not_space( std::string &s)
        {
        char chSpace = ' ';
        return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
        std::not_equal_ to<char>());
        }
        I'm not sure I understand. If all you're looking for is the
        next non-space, std::find_if should work using the standard
        functional objects, e.g.:
        std::find_if(
        begin, end,
        std::bind2nd( std::not_equal_ to< char >( ' ' ) ) ) ;

        Generally speaking, however, this isn't a good idea, since it
        doesn't consider things like '\t' as spaces. I usually use
        functional object wrappers for ctype<>::is(), with the
        appropriate mask.

        --
        James Kanze (GABI Software) email:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        • James Kanze

          #5
          Re: Not-equal string searching

          On Feb 10, 12:12 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
          DavidW wrote:
          b) Also notice the member function find_first_not_ of of
          std::string. It almost does what you want, except that it
          returns the index of the element and not an iterator.
          To get the iterator, of course, just add it to begin(). I still
          prefer std::find_if, since it's what I'd do with any other
          container.

          --
          James Kanze (GABI Software) email:james.kan ze@gmail.com
          Conseils en informatique orientée objet/
          Beratung in objektorientier ter Datenverarbeitu ng
          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

          Comment

          • Daniel T.

            #6
            Re: Not-equal string searching

            "DavidW" <no@email.provi dedwrote:
            Is the function below the simplest way to produce an iterator to the next
            non-space in a string? (Or the upper-bound iterator if none is found).
            Searching for a sequence is overkill and inefficient IMO.
            >
            #include <string>
            #include <algorithm>
            #include <functional>
            >
            std::string::it erator find_not_space( std::string &s)
            {
            char chSpace = ' ';
            return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
            std::not_equal_ to<char>());
            }
            Someone correct me on this, but isn't the above undefined behavior?
            chSpace isn't an array so I don't think &chSpace + 1 is valid even if it
            isn't dereferenced.

            I think it would have to be something more like:

            char chSpace[] = " ";
            return search( s.begin(), s.end(), chSpace, chSpace + 1,
            not_equal_to<ch ar>() );

            Comment

            • DavidW

              #7
              Re: Not-equal string searching

              "Daniel T." <daniel_t@earth link.netwrote
              "DavidW" <no@email.provi dedwrote:
              >
              Is the function below the simplest way to produce an iterator to the next
              non-space in a string? (Or the upper-bound iterator if none is found).
              Searching for a sequence is overkill and inefficient IMO.

              #include <string>
              #include <algorithm>
              #include <functional>

              std::string::it erator find_not_space( std::string &s)
              {
              char chSpace = ' ';
              return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
              std::not_equal_ to<char>());
              }
              >
              Someone correct me on this, but isn't the above undefined behavior?
              chSpace isn't an array so I don't think &chSpace + 1 is valid even if it
              isn't dereferenced.
              It would be invalid to dereference it even if it were an array (of length 1).
              I think it would have to be something more like:
              >
              char chSpace[] = " ";
              Except that the null terminator is a wasted character. Better would be: char
              chSpace[] = {' '};
              return search( s.begin(), s.end(), chSpace, chSpace + 1,
              not_equal_to<ch ar>() );
              I don't know if it's undefined behaviour not to use an array. It seems an
              unnecessary restriction if so.



              Comment

              • Kai-Uwe Bux

                #8
                Re: Not-equal string searching

                James Kanze wrote:
                On Feb 10, 12:12 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                >DavidW wrote:
                >
                >b) Also notice the member function find_first_not_ of of
                >std::string. It almost does what you want, except that it
                >returns the index of the element and not an iterator.
                >
                To get the iterator, of course, just add it to begin().
                I am not sure whether the index-based string function mix so well with
                iterators. I had a cursory look into the standard, but I was not able to
                confirm what happens to

                s.begin() + s.find_first_no t_of( " " );

                if find_first_not_ of() does not find anything and returns npos. My gut tells
                me, I better be worried that it might be undefined behavior.
                I still
                prefer std::find_if, since it's what I'd do with any other
                container.
                Agreed.


                Best

                Kai-Uwe Bux

                Comment

                • DavidW

                  #9
                  Re: Not-equal string searching

                  "James Kanze" <james.kanze@gm ail.comwrote
                  >On Feb 9, 11:39 pm, "DavidW" <n...@email.pro videdwrote:
                  >
                  >Is the function below the simplest way to produce an iterator to the next
                  >non-space in a string? (Or the upper-bound iterator if none is found).
                  >Searching for a sequence is overkill and inefficient IMO.
                  >
                  >#include <string>
                  >#include <algorithm>
                  >#include <functional>
                  >
                  >std::string::i terator find_not_space( std::string &s)
                  >{
                  > char chSpace = ' ';
                  > return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
                  >std::not_equal _to<char>());
                  >}
                  >
                  >I'm not sure I understand. If all you're looking for is the
                  >next non-space, std::find_if should work using the standard
                  >functional objects, e.g.:
                  std::find_if(
                  begin, end,
                  std::bind2nd( std::not_equal_ to< char >( ' ' ) ) ) ;
                  Thanks, and to the others who suggested bind2nd. I wanted to use find_if and I
                  looked for such a predicate, but obviously not hard enough.

                  I would also like a std::find with a predicate, e.g., std::find(s.beg in(),
                  s.end(), chSpace, std::not_equal_ to<char>()). It looks a little neater. The
                  current std::find is specialized for equality.
                  >Generally speaking, however, this isn't a good idea, since it
                  >doesn't consider things like '\t' as spaces. I usually use
                  >functional object wrappers for ctype<>::is(), with the
                  >appropriate mask.
                  In this case it's specific to the space character.



                  Comment

                  • Krishanu Debnath

                    #10
                    Re: Not-equal string searching

                    DavidW wrote:
                    "Daniel T." <daniel_t@earth link.netwrote
                    >"DavidW" <no@email.provi dedwrote:
                    [snip]
                    >
                    > return search( s.begin(), s.end(), chSpace, chSpace + 1,
                    > not_equal_to<ch ar>() );
                    >
                    I don't know if it's undefined behaviour not to use an array. It seems an
                    unnecessary restriction if so.
                    Yes, it is. It has to be an array object.

                    Krishanu

                    Comment

                    • Andrey Tarasevich

                      #11
                      Re: Not-equal string searching

                      Daniel T. wrote:
                      ...
                      Someone correct me on this, but isn't the above undefined behavior?
                      chSpace isn't an array so I don't think &chSpace + 1 is valid even if it
                      isn't dereferenced.
                      ...
                      It is not undefined behavior. C++ standard explicitly states that rules of
                      pointer arithmetic are immediately applicable to a standalone non-array object,
                      as if this object is an array with 1 element (see 5.7/4)

                      --
                      Best regards,
                      Andrey Tarasevich

                      Comment

                      • Jeff Schwab

                        #12
                        Re: Not-equal string searching

                        Krishanu Debnath wrote:
                        DavidW wrote:
                        >"Daniel T." <daniel_t@earth link.netwrote
                        >>"DavidW" <no@email.provi dedwrote:
                        >
                        [snip]
                        >
                        >>
                        >> return search( s.begin(), s.end(), chSpace, chSpace + 1,
                        >> not_equal_to<ch ar>() );
                        >>
                        >I don't know if it's undefined behaviour not to use an array. It seems an
                        >unnecessary restriction if so.
                        >
                        Yes, it is. It has to be an array object.
                        Could you please explain why you believe that? I'm pretty sure you're
                        mistaken.

                        Comment

                        • James Kanze

                          #13
                          Re: Not-equal string searching

                          On Feb 10, 1:37 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                          James Kanze wrote:
                          On Feb 10, 12:12 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                          DavidW wrote:
                          b) Also notice the member function find_first_not_ of of
                          std::string. It almost does what you want, except that it
                          returns the index of the element and not an iterator.
                          To get the iterator, of course, just add it to begin().
                          I am not sure whether the index-based string function mix so well with
                          iterators. I had a cursory look into the standard, but I was not able to
                          confirm what happens to
                          s.begin() + s.find_first_no t_of( " " );
                          if find_first_not_ of() does not find anything and returns
                          npos. My gut tells me, I better be worried that it might be
                          undefined behavior.
                          Good point. It would be undefined behavior.

                          --
                          James Kanze (GABI Software) email:james.kan ze@gmail.com
                          Conseils en informatique orientée objet/
                          Beratung in objektorientier ter Datenverarbeitu ng
                          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                          Comment

                          • James Kanze

                            #14
                            Re: Not-equal string searching

                            On Feb 10, 12:58 am, "Daniel T." <danie...@earth link.netwrote:
                            "DavidW" <n...@email.pro videdwrote:
                            Is the function below the simplest way to produce an
                            iterator to the next non-space in a string? (Or the
                            upper-bound iterator if none is found). Searching for a
                            sequence is overkill and inefficient IMO.
                            #include <string>
                            #include <algorithm>
                            #include <functional>
                            std::string::it erator find_not_space( std::string &s)
                            {
                            char chSpace = ' ';
                            return std::search(s.b egin(), s.end(), &chSpace , &chSpace+1,
                            std::not_equal_ to<char>());
                            }
                            Someone correct me on this, but isn't the above undefined behavior?
                            No.
                            chSpace isn't an array so I don't think &chSpace + 1 is valid
                            even if it isn't dereferenced.
                            For purposes of address calculation, a scalar object behaves
                            like an array with one element.

                            --
                            James Kanze (GABI Software) email:james.kan ze@gmail.com
                            Conseils en informatique orientée objet/
                            Beratung in objektorientier ter Datenverarbeitu ng
                            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                            Comment

                            • Ralph D. Ungermann

                              #15
                              Re: Not-equal string searching

                              Kai-Uwe Bux wrote:
                              James Kanze wrote:
                              >
                              >On Feb 10, 12:12 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                              >>DavidW wrote:
                              >>b) Also notice the member function find_first_not_ of of
                              >>std::string . It almost does what you want, except that it
                              >>returns the index of the element and not an iterator.
                              >To get the iterator, of course, just add it to begin().
                              >
                              I am not sure whether the index-based string function mix so well with
                              iterators. I had a cursory look into the standard, but I was not able to
                              confirm what happens to
                              >
                              s.begin() + s.find_first_no t_of( " " );
                              >
                              if find_first_not_ of() does not find anything and returns npos. My gut tells
                              me, I better be worried that it might be undefined behavior.
                              Yup, but good old strspn( s.c_str(), " " ) works better.

                              But I feel somewhat uneasy: should I replace a function with a clear
                              name, but confusing effect by another one with a confusing name, but a
                              straightforward result?

                              -- ralph

                              Comment

                              Working...