0

I wanted to know what the difference between the two codes is. When I use .c_str() it does not work

std::vector<std::pair<std::string, std::string> >::iterator it

for(;it!=MySet.end();++it)
{
        if(std::get<1>(*it).c_str()=="PAUSE")  //Why it works only with std::get<1>(*it) and not with std::get<1>(*it).c_str()
        {
            TempDefaultVan = std::get<0>(*it).c_str();
        }
}
MistyD
  • 16,373
  • 40
  • 138
  • 240
  • 3
    With c_str() you're comparing the pointers to chars, not the actual sequence of characters. – Borgleader Feb 19 '14 at 18:31
  • `c_str()` returns a `const char *`, and pointer comparison is only "true" when the points point to the same memory location (which is *not* what you want). You want to compare the contents. – crashmstr Feb 19 '14 at 18:32
  • http://stackoverflow.com/questions/1534399/whats-the-difference-between-stdstringc-str-and-stdstringdata http://stackoverflow.com/questions/194634/string-c-str-vs-data – ɹɐqʞɐ zoɹǝɟ Feb 19 '14 at 18:33
  • 1
    @ferozakbar this has nothing to do with `data`, but pointer comparison vs. string contents comparision. – crashmstr Feb 19 '14 at 18:34
  • 1
    `strcmp` for string pointer (`const char*`) comparison. – Brandon Feb 19 '14 at 18:36
  • @Borgleader can you put that as the answer – MistyD Feb 19 '14 at 18:36
  • @MistyD you don't need to use `strcmp`, just get rid of the `.c_str()` and let `std::string::operator==` do its job. Like you say, *it works*. – crashmstr Feb 19 '14 at 18:39
  • I understand that. I was-just curious why the actual thing wasn't working.I just got rid of c_str() and it works. I just wanted to know the reason and now I know. Waiting for an answer to close this – MistyD Feb 19 '14 at 18:44
  • @MistyD Put it below in an answer. – Borgleader Feb 19 '14 at 18:48

3 Answers3

4

So basically what is happening is .c_str() is returning a const char*. This will cause operator == to compare pointers and not the string's content. Since both of these are clearly not pointing to the same memory location (since "PAUSE" is a string literal), this will always be false.

Borgleader
  • 15,826
  • 5
  • 46
  • 62
3

std::get<1>(*it) returns an object of type std::string. This class has overload operator == to compare objects of type std::string with character arrays.

std::get<1>(*it).c_str() returns a character array. Arrays have no the comparison operator. To compare character arrays you should use standard C function std::strcmp

So you could write

if( std::strcmp( std::get<1>(*it).c_str(), "PAUSE" ) == 0 )

If you will write simply as

if(std::get<1>(*it).c_str()=="PAUSE")  

then the compiler will compare two pointers because it converts arrays to pointers to their first elements in such expressions. And as the result this expression will be equal always to false if the arrays occupy different areas of memory.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

This code:

std::get<1>(*it).c_str()=="PAUSE"

is comparing two const char *, which both point to strings. This is not what you usually want when comparing strings, as it will only evaluate to true when they point to the same place in memory.

This code:

std::get<1>(*it)=="PAUSE"

Will use std::string::operator== to compare the contents of the std::string std::get<1>(*it) with the contents of "PAUSE". If you instead had two char * values, you could use strcmp, but since you have a std::string, this is the best way to make the comparison (and, as you say, "it works").

crashmstr
  • 28,043
  • 9
  • 61
  • 79