comparing string elements

Discussion in 'C++' started by MC felon, Feb 20, 2008.

  1. MC felon

    MC felon Guest

    what's the best way to compare two string elements?

    std::string cstr;
    if ( cstr.at(3) == cstr.at(2)) //do something
    or
    std::string cstr;
    if ( cstr[3] == cstr[2]) //do something

    ?
     
    MC felon, Feb 20, 2008
    #1
    1. Advertising

  2. MC felon wrote:
    > what's the best way to compare two string elements?
    >
    > std::string cstr;
    > if ( cstr.at(3) == cstr.at(2)) //do something
    > or
    > std::string cstr;
    > if ( cstr[3] == cstr[2]) //do something


    That depends.

    Do you know that cstr has at least 4 chars ? Do you want it to throw an
    exception if it does not ?

    operator[] will not check for out of bounds access while at should.

    I think for readability, operator[] is probably easier but it really
    makes very little practical difference.
     
    Gianni Mariani, Feb 20, 2008
    #2
    1. Advertising

  3. MC felon

    Jim Langston Guest

    MC felon wrote:
    > what's the best way to compare two string elements?
    >
    > std::string cstr;
    > if ( cstr.at(3) == cstr.at(2)) //do something
    > or
    > std::string cstr;
    > if ( cstr[3] == cstr[2]) //do something
    >
    > ?


    [] is a *little* faster, but should only be used when it is known that the
    length of the string is greater than the index. If it is not sure, .at()
    should be used.

    I.E.

    if ( cstr.size() < index )
    {
    if ( cstr[index] == cstr[index] // do something
    }

    Of course, that check for size() brings it's own overhead, so in that case
    just use .at(). However, at lot of times at the beginning of a function I
    will validate sizes and throw an error or return with an empty string. So
    in my base I know the size indexes will fit, so then I will just use []

    Realistically, I never use .at() because I always check the length of the
    strings before I do operations on them. I would rather check on error
    conditions in code rather than have to depend on throws.

    --
    Jim Langston
     
    Jim Langston, Feb 20, 2008
    #3
  4. MC felon

    MC felon Guest

    Thanks. The problem is i'm programming a Tic Tac Toe game and the AI
    just isn't working! I think there's something wrong with the way i'm
    comparing the strings.
     
    MC felon, Feb 20, 2008
    #4
  5. On 20 Feb, 13:30, MC felon <> wrote:
    > Thanks. The problem is i'm programming a Tic Tac Toe game and the AI
    > just isn't working! I think there's something wrong with the way i'm
    > comparing the strings.


    <OT>
    whilst I know what you mean, 'AI' seems a very grandiose
    term for Tic Tac Toe - I mean, I once wrote a passable
    implementation on a programmable calculator !
    </OT>
     
    tragomaskhalos, Feb 20, 2008
    #5
  6. MC felon

    James Kanze Guest

    On Feb 20, 9:55 am, Gianni Mariani <> wrote:
    > operator[] will not check for out of bounds access while at should.


    That's a quality of implementation issue. In the libraries I use
    most often, operator[] does bounds checks, aborting the program
    if the index is out of bounds. At() guarantees an exception,
    which is rarely what you want.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Feb 20, 2008
    #6
  7. MC felon

    James Kanze Guest

    On Feb 20, 11:23 am, "Jim Langston" <> wrote:
    > MC felon wrote:
    > > what's the best way to compare two string elements?


    > > std::string cstr;
    > > if ( cstr.at(3) == cstr.at(2)) //do something
    > > or
    > > std::string cstr;
    > > if ( cstr[3] == cstr[2]) //do something


    > > ?


    > [] is a *little* faster, but should only be used when it is
    > known that the length of the string is greater than the index.
    > If it is not sure, .at() should be used.


    If using an out of bounds index is an error, you should use [],
    rather than at(). At least with the implementations I use, []
    treats an out of bounds index as an error condition; at() treats
    it as an exceptional (but not wrong) situation.

    > I.E.


    > if ( cstr.size() < index )
    > {
    > if ( cstr[index] == cstr[index] // do something
    > }


    > Of course, that check for size() brings it's own overhead, so
    > in that case just use .


    More frequently, you'll have something like:

    assert( index < cstr.size() ) ;

    Except, of course, that this code is normally in the operator[]
    function itself.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Feb 20, 2008
    #7
  8. MC felon

    Jim Langston Guest


    "James Kanze" <> wrote in message
    news:...
    On Feb 20, 11:23 am, "Jim Langston" <> wrote:
    > MC felon wrote:
    > > what's the best way to compare two string elements?


    > > std::string cstr;
    > > if ( cstr.at(3) == cstr.at(2)) //do something
    > > or
    > > std::string cstr;
    > > if ( cstr[3] == cstr[2]) //do something


    > > ?


    > [] is a *little* faster, but should only be used when it is
    > known that the length of the string is greater than the index.
    > If it is not sure, .at() should be used.


    If using an out of bounds index is an error, you should use [],
    rather than at(). At least with the implementations I use, []
    treats an out of bounds index as an error condition; at() treats
    it as an exceptional (but not wrong) situation.

    > I.E.


    > if ( cstr.size() < index )
    > {
    > if ( cstr[index] == cstr[index] // do something
    > }


    > Of course, that check for size() brings it's own overhead, so
    > in that case just use .


    More frequently, you'll have something like:

    assert( index < cstr.size() ) ;

    Except, of course, that this code is normally in the operator[]
    function itself.

    ============

    I see a different result. This program in debug mode:

    #include <vector>
    #include <iostream>

    int main()
    {
    std::vector<int> data(5);

    try
    {
    data.at(5) = 5;
    }
    catch (...)
    {
    std::cout << "Error1\n";
    }

    try
    {
    // Causes run time overflow
    data[5] = 5;
    }
    catch (...)
    {
    std::cout << "Error2\n";
    }
    }

    will output
    "Error1"

    then tell me that memory has been corrupted.

    That being the case isn't it opposite of what you say? That if an overflow
    is an error condition then .at() should be used.

    I was always lead to be leive that at() would throw on overflow, [] would
    not check.
     
    Jim Langston, Feb 21, 2008
    #8
  9. MC felon

    James Kanze Guest

    On Feb 21, 4:07 am, "Jim Langston" <> wrote:
    > > "James Kanze" <> wrote in message
    > > news:....


    > > If using an out of bounds index is an error, you should use
    > > [], rather than at(). At least with the implementations I
    > > use, [] treats an out of bounds index as an error condition;
    > > at() treats it as an exceptional (but not wrong) situation.


    > > > I.E.
    > > > if ( cstr.size() < index )
    > > > {
    > > > if ( cstr[index] == cstr[index] // do something
    > > > }
    > > > Of course, that check for size() brings it's own overhead, so
    > > > in that case just use .


    > > More frequently, you'll have something like:


    > > assert( index < cstr.size() ) ;


    > > Except, of course, that this code is normally in the
    > > operator[] function itself.


    > I see a different result. This program in debug mode:


    > #include <vector>
    > #include <iostream>


    > int main()
    > {
    > std::vector<int> data(5);


    > try
    > {
    > data.at(5) = 5;
    > }
    > catch (...)
    > {
    > std::cout << "Error1\n";
    > }


    > try
    > {
    > // Causes run time overflow
    > data[5] = 5;
    > }
    > catch (...)
    > {
    > std::cout << "Error2\n";
    > }
    > }


    > will output
    > "Error1"


    > then tell me that memory has been corrupted.


    I get:
    Error1
    /home/team02/jakan/gnu/gcc/install-4.1.0/sparc/lib/gcc/sparc-sun-
    solaris2.8/4.1.0/../../../../../include/c++/4.1.0/debug/vector:192:
    error: attempt to subscript container with out-of-bounds index
    5, but
    container only holds 5 elements.

    Objects involved in the operation:
    sequence "this" @ 0xffbedf34 {
    type = N15__gnu_debug_def6vectorIiSaIiEEE;
    }
    Abort (core dumped)

    That's with g++ (4.1.0). I don't have access to a version of
    VC++ at the moment (my PC was "upgraded", and all of the
    software I installed myself was lost), so I can't check, but I'm
    pretty sure that I've checked this in the past, and VC++ (the
    Studios 2005 version) also caught the error (with the options I
    normally used---since my .bashrc was also lost in the upgrade, I
    can't tell you what they were, except that they were called
    $VCPPFLAGS:).

    > That being the case isn't it opposite of what you say? That
    > if an overflow is an error condition then .at() should be
    > used.


    At throws an exception. That's NOT what you want in case of a
    software error.

    > I was always lead to be leive that at() would throw on
    > overflow, [] would not check.


    at() is guaranteed to throw, and should be used if you are
    prepared to handle the case at some higher level. [] is
    undefined behavior, and will cause something similar to an
    assertion failure in a good implementation of the library (with,
    of course, the possibility of turning the testing off if the
    profiler says you have to).

    It is regrettable that these checks aren't on by default with
    g++, but then, the defaults aren't generally usable for any
    compiler I've seen.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Feb 21, 2008
    #9
    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. farah
    Replies:
    22
    Views:
    1,759
    Remon van Vliet
    Apr 3, 2006
  2. Ex-Em-El
    Replies:
    0
    Views:
    381
    Ex-Em-El
    Aug 5, 2004
  3. Varun Sinha

    Comparing elements of an array to a char

    Varun Sinha, Nov 24, 2003, in forum: C Programming
    Replies:
    9
    Views:
    431
    Irrwahn Grausewitz
    Nov 25, 2003
  4. Replies:
    3
    Views:
    269
    Asun Friere
    Jul 10, 2007
  5. Shriphani
    Replies:
    9
    Views:
    342
    Gabriel Genellina
    Sep 28, 2007
Loading...

Share This Page