In short I am getting different output for string comparison using string::compare() vs relational operator '<' on std::string class objects.
string str = "100";
cout << str.compare("10")<<endl; //prints 1
cout << ("100" < "10") <<endl; //prints 1
Here's the demo url
lexicographically "100" is greater than "10" and hence ("100" <"10") must print 0 since it's false but the output 1 i.e true is not expected.
The str.compare() function returns > 0 which is expected validating "100" > "10".
Why is this happening?
In this statement
cout << ("100" < "10") <<endl;
you are comparing two pointers of the type const char * to which the used string literals are implicitly converted. The result of such a comparison is undefined (At least in the C Standard there is explicitly stated that such operation is undefined).
In fact the above statement is equivalent to
cout << ( &"100"[0] < &"10"[0] ) <<endl;
If you want to compare strings the you need to write at least like
cout << (std::string( "100" ) < "10") <<endl;
In this case the output will be
0
Pay attention to that according to the C++ 20 (7.6.9 Relational operators)
...The comparison is deprecated if both operands were of array type prior to these conversions
And the both string literals prior to comparison have array types.
Related
I am facing a error when compiling my c++ code,
when hovering over it, it says error:-
no operator ">=" matches these operands -- operand types are: std::__cxx11::string >= intC/C++(349).
the code goes like this, its a function in a structure, which takes an array variable from the same structure and runs a loop to check the values in that array is greater or equal to 999,
ERROR IS ON THE LINE - if ((PowerChecker.cpower[a] >= 999))
I AM NOT ALLOWED TO COMPARE ARRAY
customers InputChecker(struct customers PowerChecker)
{
for (int a = 0; a < 4; a++)
{
if ((PowerChecker.cpower[a] >= 999))
{
cout << "Please re-specify the power of your character" << PowerChecker.cpower[a] << endl;
cout << "Power shoudl not Excced Limit 999 " <<endl;
}
}
return (PowerChecker);
}
here is the image of error after compiling
EDIT: SOLVED
As Peter and drescherjm wrote in the comments, it seems that you try to compare a string to an integer. You will need to convert the string first. Many ways how to do this can be found here: How can I convert a std::string to int?
Given the below piece of C++ code
cout<<("100">"035")<<"\n";
cout<<("100"<"035")<<"\n";
string str = "100";
cout<<str.compare("035");
The output of this code is
0
1
1
Which means "100" < "035" by the operator but "100" > "035" by the compare function. Is there any known implementation differences of these two?
P.S. "100" > "035" definitely makes more sense.
C-String literals (such as "100") compare themselves as pointer.
std::string comparison compare content lexicography.
If you want consistent results:
using namespace std::string_literals;
std::cout << ("100"s > "035"s)<<"\n";
std::cout << ("100"s < "035"s)<<"\n";
std::string str = "100"s;
std::cout << str.compare("035");
"100"s is "equivalent" to std::string("100").
I am trying to understand how the ternary operator works in C++.
I expect to see the same output for both print statements, yet the second print statement outputs 49.
Why is this?
#include <iostream>
using namespace std;
int main()
{
int test = 0;
cout << "First character " << '1' << endl;
cout << "Second character " << (test ? 3 : '1') << endl;
return 0;
}
Output:
First character 1
Second character 49
'1' got converted to an integer which represented the ASCII code for '1'. The ternary operator is supposed to have two values of the same type. You can not have 3 (an integer) and '1' (a char). That's why the conversion took place. If the implicit conversion could not have happened then a compiler error would have been generated.
This question already has an answer here:
The output of cout << 1 && 0;
(1 answer)
Closed 7 months ago.
Consider:
int i = 56, j = 0;
int n = i&&j;
cout << i&&j;
cout << endl << n;
whose output would be:
56
0
I imagine it's either because of operator precedence or logical short circuit, but I can't seem to figure out which, or the reason.
The expression cout << i&&j is equivalent to (cout << i) && j. Both operands are evaluated and converted to bool. The statement as a whole has no effect, but the evaluation of the subexpression cout << i has the usual side effects, of course, namely writing something to the standard output.
The && operator is indeed short-circuited and j is only evaluated if cout << i evaluates as true. This condition is equivalent to cout.good(), which is usually the case (unless you somehow managed to close your standard output).
As you expected, the << operator comes takes precedence over &&.
Thus, cout << i&&j first outputs i, then compares the returned stream to j (both are true, so the returned value is true, but this value is discarded).
See here for the full list of operator precedence.
I have a question:
Let's say there are two std::strings and I want to compare them, there is the option of using the compare() function of the string class but I also noticed that it is possible using simple < > != operators (both of the cases are possible even if I don't include the <string> library).
Can someone explain why the compare() function exists if a comparison can be made using simple operators?
btw I use Code::Blocks 13.12
here is an example of my code:
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::getline;
int main()
{
string temp1, temp2;
cout << "Enter first word: ";
getline (cin,temp1);
cout << "Enter second word: ";
getline (cin,temp2);
cout << "First word: " << temp1 << endl << "Second word: " << temp2 << endl;
if (temp1 > temp2)
{
cout << "One" << endl;
}
if (temp1.compare(temp2) < 0)
{
cout << "Two" << endl;
}
return 0;
}
.compare() returns an integer, which is a measure of the difference between the two strings.
A return value of 0 indicates that the two strings compare as equal.
A positive value means that the compared string is longer, or the first non-matching character is greater.
A negative value means that the compared string is shorter, or the first non-matching character is lower.
operator== simply returns a boolean, indicating whether the strings are equal or not.
If you don't need the extra detail, you may as well just use ==.
string cat = "cat";
string human = "human";
cout << cat.compare(human) << endl;
This code will give -1 as a result. This is due to the first non-matching character of the compared string 'h' is lower or appears after 'c' in alphabetical order, even though the compared string, 'human' is longer than 'cat'.
I find the return value described in cplusplus.com is more accurate which are-:
0 : They compare equal
<0 : Either the value of the first character that does not match is lower in the compared string, or all compared characters match but the compared string is shorter.
more than 0 : Either the value of the first character that does not match is greater in the compared string, or all compared characters match but the compared string is longer.
Moreover, IMO cppreference.com's description is simpler and so far best describe to my own experience.
negative value if *this appears before the character sequence specified by the arguments, in lexicographical order
zero if both character sequences compare equivalent
positive value if *this appears after the character sequence specified by the arguments, in lexicographical order
Regarding the question,
” can someone explain why the compare() function exists if a comparison can be made using simple operands?
Relative to < and ==, the compare function is conceptually simpler and in practice it can be more efficient since it avoids two comparisons per item for ordinary ordering of items.
As an example of simplicity, for small integer values you can write a compare function like this:
auto compare( int a, int b ) -> int { return a - b; }
which is highly efficient.
Now for a structure
struct Foo
{
int a;
int b;
int c;
};
auto compare( Foo const& x, Foo const& y )
-> int
{
if( int const r = compare( x.a, y.a ) ) { return r; }
if( int const r = compare( x.b, y.b ) ) { return r; }
return compare( x.c, y.c );
}
Trying to express this lexicographic compare directly in terms of < you wind up with horrendous complexity and inefficiency, relatively speaking.
With C++11, for the simplicity alone ordinary less-than comparison based lexicographic compare can be very simply implemented in terms of tuple comparison.