一. 前言
在最近写代码中,遇到了strcmp/strncmp比较失败的问题,由此引出此文的讨论分析。
二. 分析
首先看看strcmp的源码:
int strcmp ( const char* src, const char* dst )
{
int ret = 0 ;
while( !(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
其实就是对src和dst每一位求ASCII码并相减,等于0则继续,否则退出比较,根据结果返回大于0,小于0或者等于0。但是,必须注意这里还有个判断条件:*dst > 0。这就是本文错误的根源所在了。请看下面的例子test1():
#include <iostream>
void test1()
{
char msg[] = { 0, 0, 0, 1, 5 };
char choke[] = { 0, 0, 0, 1, 0 };
int cmp1 = strcmp(msg, choke);
int cmp2 = strcmp(choke, msg);
std::cout << cmp1 << std::endl;
std::cout << cmp2 << std::endl;
}
int main()
{
test1();
getchar();
}
test1()的比较结果是返回0,即相同,这显然就是由于该问题导致的。因此,当使用strcmp/strncmp比较时,最好避开含有0的字符串的比较。
三. 十六进制和十进制的问题
直接看代码:
void test2()
{
char msg[] = { 0, 0, 0, 1, 5 };
char interest[] = { 0, 0, 0, 1, 2 };
char unintrest[] = { 0, 0, 0, 1, 3 };
char tmp = *(msg + 4);
char tmp2 = *(interest + 4);
char tmp3 = *(unintrest + 4);
if (tmp == '\x5')
{
std::cout << "tmp equal" << std::endl;
}
if (tmp2 == '\x2')
{
std::cout << "tmp2 equal" << std::endl;
}
if (tmp3 == '\x3')
{
std::cout << "tmp3 equal" << std::endl;
}
}
该例子想说的其实很简单,我们在赋值字符串数组的时候,填写的数字,会被转译成为十六进制。若这里使用十进制‘5’,‘2’,‘3’进行比较,是不会得到正常的结果的。有人想说如果想要得到十进制怎么办,很简单,赋值的时候单独给该为赋值‘5’,‘2’,‘3’即可实现。
欢迎关注本人公众号,公众号会更新一些不一样的内容,相信一定会有所收获。