Reputation: 2934
So I am trying to simply do a std::string == "string-literal"
which would work just fine, except that I am creating my string with
std::string str(strCreateFrom, 0, strCreateFrom.find(' '));
and find returns string::npos
now both of these contain the string "submit"
however ==
returns false, now I have narrowed this down to the fact that the sizes are "different" even though they really aren't. str.size()
is 7 and strlen("submit")
is 6. Is this why ==
is failing, I assume it is but I don't see why... shouldn't it check to see if the last char of dif is \0
as is the case in this situation?
And is there anyway that I can get around this without having to using compare and specify the length to compare or change my string?
Edit:
std::string instruction(unparsed, 0, unparsed.find(' '));
boost::algorithm::to_lower(instruction);
for(int i = 0; i < instruction.size(); i++){
std::cout << "create from " << (int) unparsed[i] << std::endl;
std::cout << "instruction " << (int) instruction[i] << std::endl;
std::cout << "literal " << (int) "submit"[i] << std::endl;
}
std::cout << (instruction == "submit") << std::endl;
prints
create from 83
instruction 115
literal 115
create from 117
instruction 117
literal 117
create from 98
instruction 98
literal 98
create from 77
instruction 109
literal 109
create from 105
instruction 105
literal 105
create from 116
instruction 116
literal 116
create from 0
instruction 0
literal 0
0
EDIT:
For more clarification as to why I'm confused I read the basic_string.h header and saw this:
/**
* @brief Compare to a C string.
* @param s C string to compare against.
* @return Integer < 0, 0, or > 0.
*
* Returns an integer < 0 if this string is ordered before @a s, 0 if
* their values are equivalent, or > 0 if this string is ordered after
* @a s. Determines the effective length rlen of the strings to
* compare as the smallest of size() and the length of a string
* constructed from @a s. The function then compares the two strings
* by calling traits::compare(data(),s,rlen). If the result of the
* comparison is nonzero returns it, otherwise the shorter one is
* ordered first.
*/
int
compare(const _CharT* __s) const;
Which is called from operator== so I am trying to find out why the size dif matters.
Upvotes: 2
Views: 4470
Reputation: 144
I didn't quite understand your question more details may be needed, but you can use the c compare which shouldn't have issues with null termination counting. You could use:
bool same = (0 == strcmp(strLiteral, stdTypeString.c_str());
strncmp also can be used to compare only a given number of chars in a char array
Or try to fix the creation of the stdstring
Your unparsed std::string is already bad. It already contains the extra null in the string, so what you should look at is how it is being created. Like I mentioned before mystring[mystring.size() -1] is the last character not the terminating null so if you see a '\0' there like you do in your output it means the null is treated like part of the string.
Try to trace back your parsed input and keep making sure that mystring[mystring.size() -1] is not '\0'.
To answer your size diff question: The two strings are not the same the literal is shorter and doesn't have a null.
Compare stops comparing when it reaches the the terminating null in the literal but it uses the stored size for the std::string which is 7 seeing that literal terminated at 6 but the std is size 7 it will say that std is larger.
I think if you do the following it will return that the strings are the same (because it will create an std string with an extra null on the right side as well):
std::cout << (instruction == str("submit", _countof("submit"))) << std::endl;
PS: This is a common error made when taking a char* and making an std::string out of it, frequently just the array size itself is used, but that includes the terminating zero which std::string will add anyway. I believe that something like this is happening to your input somewhere and if you get add a -1 wherever that is everything will work as expected.
Upvotes: 1