Reputation: 107
I expect "match!" when the n2
tail is the same that the n1
tail, otherwise, "do not match!".
Example of "match!": n1 = 123456
and n2 = 3456
.
The problem is when I enter, for example, n1 = "45"
and n2 = "645"
. It should not match, but the output is "match!".
bool different_tail = false;
char n1[11], n2[11];
cin >> n1 >> n2;
for(int i = strlen(n1)-strlen(n2); i < strlen(n1); i++){
if(i < 0 || n1[i] != n2[i-(strlen(n1)-strlen(n2))]){
different_tail = true;
break;
}
}
if(different_tail)
cout << "does not match!" << endl;
else
cout << "match!" << endl;
I don't want to use other ways to solve the problem (like, strcmp, etc...), I want to understand what's happening.
Upvotes: 0
Views: 106
Reputation: 94529
What happens is that with n1
being 45
and n2
being 645
, the loop variable i
will start at -1
, i.e. it is negative.
However, strlen
yields an unsigned value (a value of type size_t
). When comparing a signed with an unsigned value (as you do in the expression i < strlen(n1)
), the signed value is converted to an unsigned value. Since it's negative, this causes an underflow, so i
is a very large value -- larger than strlen(n1)
.
You can observe the same effect with e.g.
int i = -1;
size_t x = 5;
if (i < x) {
cout << "yes\n";
} else {
cout << "no\n";
}
This program prints no
.
You can avoid your issue by casting the return value of strlen
, i.e. change your loop condition to
i < static_cast<int>(strlen(n1))
This question (and the accompanying answers) provide a more in-depth discussion of this topic.
Upvotes: 3
Reputation: 148
Look at this line:
for(int i = strlen(n1)-strlen(n2); i < strlen(n1); i++){
here i
is an int
whereas strlen(n1)
is an size_t
(an unsigned integer type). Performing "less than" operator between signed and unsigned type will convert all operands to unsigned types, in this case unsigned(i)
becomes a very large integer, so the for loop is never executed.
BTW, it's not a good practice to use strlen
in for loop, since strlen
is an expensive function and will be called at every iteration. You can store strlen
result in an variable and use the variable instead.
Upvotes: 0