简述strcmp/strncmp比较失败的问题

本文深入探讨了在使用strcmp和strncmp函数时遇到的比较失败问题,特别是在处理包含0值字符的字符串时。同时,文章揭示了在初始化字符串数组时,数值被转译成十六进制的细节,提醒开发者在比较时需注意数据类型的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 前言

  在最近写代码中,遇到了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’即可实现。


欢迎关注本人公众号,公众号会更新一些不一样的内容,相信一定会有所收获。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ch_ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值