C字符串的奇怪结果

时间:2016-01-13 13:06:36

标签: c++ string strlen

我期待"匹配!"当n2尾部与n1尾部相同时,否则"不匹配!"。 "匹配的示例!":n1 = 123456n2 = 3456

问题出在我输入时,例如n1 = "45"n2 = "645"。它不应该匹配,但输出是#34;匹配!"。

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;

我不想用其他方法解决问题(例如,strcmp等等),我想了解发生了什么。

2 个答案:

答案 0 :(得分:3)

如果n145n2645,则循环变量i将从-1开始,即这是消极的。

但是,strlen会产生无符号值(类型为size_t的值)。将有符号值与无符号值进行比较时(如表达式i < strlen(n1)中所做的那样),有符号值将转换为无符号值。由于它是负数,因此导致下溢,因此i是一个非常大的值 - 大于strlen(n1)

您可以观察到相同的效果,例如

int i = -1;
size_t x = 5;
if (i < x) {
  cout << "yes\n";
} else {
  cout << "no\n";
}

此程序打印no

您可以通过转换strlen的返回值来避免您的问题,即将您的循环条件更改为

i < static_cast<int>(strlen(n1))

This question(以及随附的答案)对此主题进行了更深入的讨论。

答案 1 :(得分:0)

看看这一行:

for(int i = strlen(n1)-strlen(n2); i < strlen(n1); i++){

此处iint,而strlen(n1)size_t(无符号整数类型)。表演&#34;小于&#34;有符号和无符号类型之间的运算符会将所有操作数转换为无符号类型,在这种情况下,unsigned(i)变为一个非常大的整数,因此永远不会执行for循环。

顺便说一下,在for循环中使用strlen不是一个好习惯,因为strlen是一个昂贵的函数,并且会在每次迭代时调用。您可以将strlen结果存储在变量中,而是使用变量。