• holy shit now I'm actually commenting here... (unregistered)

    There's also the delightfully readable version someString.rfind(substring, 0) == frist that doesn't waste time looking at any position other than the start! (assume a variable frist with the value zero)

  • (nodebb)

    As is common, strncmp returns 0 if the two strings are equal, so we negate that to say "if the symTabName starts with prefix, do stuff".

    This, in and of itself, is substantial wrongness, because you should make it more readable by comparing the result of the funtion to zero :

    `strncmp( pdf->symTabName().c_str(), prefix.c_str(), strlen( prefix.c_str() ) ) == 0`
    

    But in 2007-era C++, probably mostly C++98, it should be if ( pdf->symTabName().substr(0, prefix.length()) == prefix )

  • David-T (unregistered)

    Anyone who fails to put a space between the if and the mandatory opening parenthesis should be banned from touching a keyboard ever again

  • Hanzito (unregistered)

    Are you suggesting to search the whole string to see if it's the actual start? I don't know how big these strings are, but performance-wise that is not great, for something that is hardly more readable. Better to write a stringStartsWith() utility function.

  • holy shit now I'm actually commenting here... (unregistered) in reply to Steve_The_Cynic

    rfind is (supposed to) be in C++98 and it doesn't need to allocate/copy a substring

  • PlasticHound (unregistered) in reply to holy shit now I'm actually commenting here...

    The ::rfind() method is the correct answer.

    The one in the text:

    if(pdf->symTabName().find(prefix) != 0UL) is, I think, wrong as that's only going to work if the prefix isn't at the start [when it does ==0] and that includes not existing at all as ::find() will return npos if the prefix isn't in the string. And because that's a std::size_t it'll be comparable to 0...

  • (nodebb)

    I am always amazed at how important the original C standards body thought that strings being "greater" or "lesser" was.

  • Malte (unregistered)

    I consider none of the code-examples, including the ones suggested in the comments so far, readable. Readable would be to give it a speaking name. For example, if starts_with_prefix(pdf->symTabName(), prefix). I see no upside in calling .c_str() multiple times outside the function-call or in keeping the line that long. One of the great benefit of functions is the possibility to give non-interacting code-sections a name.

  • holy shit now I'm actually commenting here... (unregistered) in reply to Malte

    You are absolutely right! (omg, I swear I'm not a robot >.<) Calling "using the search function that starts at the end to check for 'starts with'" readable was with my tongue fimly planted in cheek.

  • (nodebb)

    There's lots and lots of bad code posted here in the TDWTF comments due to sloppy reading, sloppy thinking, and sloppy typing (with no edit function). I'm certainly guilty of all three at one time or another.

    If you're going to deliberately write bad code for humor, it probably needs some kind of sarcasm indicator. e.g.

    [SarcasmAttribute(severity=2)]
    {
      Public BadEnum
      {
        Secnod,
        frist, 
        FILE_NOT_FNOUD
      }
    }
    
  • D-Coder (unregistered) in reply to davethepirate

    I am always amazed at how important the original C standards body thought that strings being "greater" or "lesser" was.

    I'm guessing there was a PDP-11 instruction that did that.

  • Argle (unregistered)

    In 1999, I was probably my city's leading expert in C++. I taught on-site C++ courses to a few large companies, including a major airline. 27 years later, I'm working for one of those companies full-time, but I went cold turkey in 2000 and became a C# expert instead. Last year, I had to do a presentation of identical code done in JavaScript, C#, and C++. In the 25+ years I had been away from C++, I came back to find a lot of radical changes. But the changes to the string libraries that I found in every other language since that time simply were not there. I can't do x.trim().tolower(). And I can't get good answers to this, even though I work with a member of the C++ standards committee. To me, C++ is starting to feel like it's aged to the point that it's reactionary, not progressive.

  • Klimax (unregistered) in reply to Argle

    Sorry, but that is only your opinion that C++ is regressive.

    As if other languages don't suffer from massive bloat of various non-core elements…. and still missing useful found in C++.

  • std::less() (unregistered) in reply to davethepirate

    I like the std::string::operator<(), because it allows std::string to be used in std::map and others as key. Makes the handling of strings feel much more like first class citizens.

  • (nodebb) in reply to std::less()

    If you are using strings as the keys in a map, there better be only six or seven entries because that does NOT scale well.

  • FTB (unregistered) in reply to davethepirate
    I am always amazed at how important the original C standards body thought that strings being "greater" or "lesser" was.

    It's almost as if they knew people would want to sort them in alphabetical order.

  • (nodebb) in reply to PlasticHound

    The ::rfind() method is the correct answer.

    The one in the text:

    if(pdf->symTabName().find(prefix) != 0UL) is, I think, wrong as that's only going to work if the prefix isn't at the start [when it does ==0] and that includes not existing at all as ::find() will return npos if the prefix isn't in the string. And because that's a std::size_t it'll be comparable to 0...

    The reason that it's wrong with .find() != 0UL is merely that the sense of the test is inverted (change "!=" to "==", and you're good).

    And find() is better than rfind in an important way, especially if the names are long, because find() begins searching at the place where the prefix is, i.e. at the beginning. rfind() begins at the other end. If it's common that the names are long and the prefix is not, you'll spend time looking at places where the prefix isn't.

    But most of all, rfind is absolutely wrong because e.g. "abcdabcd"s.rfind("a") also returns the wrong thing (4uz) if the prefix appears twice, once at the beginning and once somewhere else. (It returns the second, but not the first, and the code decides that the prefix isn't there.) "abcdabcd"s.find("a") correctly returns 0uz because the prefix is there.

  • PlasticHound (unregistered) in reply to Steve_The_Cynic

    ::rfind("a") would indeed start from the end, but that's not what was said. The optional pos param defaults to npos but by specifying 0, we ensure the search starts at the first character. If that fails, we don't look up the string, as we're already there.

  • (nodebb) in reply to davethepirate

    I am always amazed at how important the original C standards body thought that strings being "greater" or "lesser" was.

    Sorting lists of strings alphabetically has always been a useful function to make it easier for humans to find items in them.

    If there's a defined collation order of strings (in whatever language you use and whatever alphabet) then there's a well defined "greater than" function that is quite useful for sorting lists of strings.

    When strcmp was thought of, the only sort order available was by using the ASCII values. It worked reasonably well until non Americans wanted sorted string lists.

  • (nodebb) in reply to davethepirate

    If you are using strings as the keys in a map, there better be only six or seven entries because that does NOT scale well.

    Unless the keys are quite long making the comparison expensive, it scales as well as using pretty much anything as the keys.

  • holy shit now I'm actually commenting here... (unregistered) in reply to Steve_The_Cynic

    Hehe, you're exactly proving my point about the readability. As PlasticHound points out, the zero pos argument is essential and what makes it the correct solution, but it is a real headscratcher and should definitely be wrapped in a startsWith function.

  • (nodebb)

    C++ is the only language I've tried to learn and gave up. This reminds me why.

  • (nodebb)

    I completely forgot I submitted this one. I've seen so much worse now that I'd barely stop to give something like this a second thought.

    P.S. It's not company code. It's academic FOSS.

Leave a comment on “Non-cogito Ergo c_str”

Log In or post as a guest

Replying to comment #:

« Return to Article