奇怪的结果与C字符串
我期待“匹配!”当n2
的尾部与n1
尾部相同时,否则“不匹配!”。 “匹配!”的示例:n1 = 123456
和n2 = 3456
。奇怪的结果与C字符串
问题出在我输入时,例如n1 = "45"
和n2 = "645"
。它不应该匹配,但输出是“匹配!”。
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等),我想了解发生了什么。
会发生什么情况是,随着n1
是45
和n2
是645
,循环变量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(和附带的答案)提供这个话题更深入的讨论。
哦,我知道了。对我来说非常奇怪。非常感谢! – WithoutNameZin
看这个行:
for(int i = strlen(n1)-strlen(n2); i < strlen(n1); i++){
i
这里是一个int
而strlen(n1)
是size_t
(无符号整型)。在有符号和无符号类型之间执行“小于”运算符会将所有操作数转换为无符号类型,在这种情况下,unsigned(i)
将变成一个非常大的整数,因此永远不会执行for循环。
顺便说一句,在for循环中使用strlen
并不是一个好习惯,因为strlen
是一个昂贵的函数,并且将在每次迭代中调用。您可以将strlen
结果存储在变量中,然后使用该变量。
谢谢,我不知道! – WithoutNameZin
这听起来像你可能需要学习如何使用调试器来逐步执行代码。使用一个好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏离的位置。如果你打算做任何编程,这是一个重要的工具。进一步阅读:** [如何调试小程序](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)** – NathanOliver
Nathan,strlen(n1)-strlen( n2)是-1,'for'没有执行......我不知道为什么。而且我无法调试其他任何东西来了解这一点。 – WithoutNameZin