0

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.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 11
    It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: **[How to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)** – NathanOliver Jan 13 '16 at 13:08
  • Nathan, strlen(n1)-strlen(n2) is -1 and the 'for' is not executed... I don't know why. And I can't debug nothing else to know about that. – WithoutNameZin Jan 13 '16 at 13:13

2 Answers2

3

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.

Community
  • 1
  • 1
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
0

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.

Ming Wei
  • 128
  • 5