WithoutNameZin
WithoutNameZin

Reputation: 107

Weird result with C strings

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

Answers (2)

Frerich Raabe
Frerich Raabe

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

Ming Wei
Ming Wei

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

Related Questions