一起talk C栗子吧(第六十六回:C语言实例--DIY字符串比较函数)



各位看官们,大家好,上一回中咱们说的是DIY字符串连接函数的例子,这一回咱们说的例子是:DIY字符串比较函数。闲话休提,言归正转。让我们一起talk C栗子吧!

我们在前面的章回中介绍过字符串比较函数,时间不长,但是有些看官已经忘记了,为了加深看官们对字符串比较函数的印象,我们准备DIY字符串比较函数。Just do it by yourself!

我们在前面的章回中一共介绍了两个字符串比较函数:strcmp,strncmp。接下来我们分别介绍如何DIY这两个字符串比较函数。

DIY strcmp函数

int diy_strcmp(const char s1, const char s2)

  • 1.在s1和s2所指向的字符串中,分别取出一个字符进行比较;
  • 2.判断这两个字符的ASCII码值大小,如果它们的值相等,那么返回第一步,比较下一个字符;否则,进入下一步;
  • 3.返回这两个字符的ASCII码差值;
  • 4.重复步骤1到3,直到取出的字符是s1或者s2的小尾巴为止。

下面是我写的代码,请大家参考:

int diy_strcmp(const char *s1, const char * s2)
{
    int res = 0;

    if(NULL == s1 || NULL == s2)
    {
        printf("NULL pointer error \n");
        return 0 ;
    }

    while(*s1 != ‘\0‘ && *s2 != ‘\0‘)
    {
        if(*s1 ==  *s2)
        {
            s1++;
            s2++;
        }
        else
        {
            res = *s1 -*s2;
            break;
        }
    }

    if(res == 0)
        res = *s1 -*s2; // the ASCII value of \0 is 0

    return res;
}

通过上面的代码,大家可以看到,我们使用两个字符的ASCII码差值做为比较的结果,并且在比较过程中计算该结果。如果没有计算该结果,可能是遇到s1或者s2的小尾巴了,那么我们再计算一次。计算的时候,巧妙利用了空字符的ASCII码值。如果在比较过程中遇到空字符,那么停止比较。这时候计算结果时,两个字符中至少有一个是空字符。而空字符的值为零,使用它减去其它字符,就会得到一个负数。使用其它字符减去它,就会得到一个正数。这也正是我们想要的结果。

下面是标准库中strcmp函数的代码,请大家和我们DIY的代码进行比较:

/**
 * strcmp - Compare two strings
 * @cs: One string
 * @ct: Another string
 */
#undef strcmp
int strcmp(const char *cs, const char *ct)
{
        unsigned char c1, c2;

        while (1) {
                c1 = *cs++;
                c2 = *ct++;
                if (c1 != c2)
                        return c1 < c2 ? -1 : 1;
                if (!c1)
                        break;
        }
        return 0;
}

通过对比,大家可以看到标准库提供的代码更加简洁一些,不过比较的思路是相同的。在返回结果中,标准库中的代码只返回-1,1和0这三种值。而我们DIY的代码中返回值与字符串中的字符有关,当然了,两个字符串相等时仍然返回1。

DIY strncmp函数

int diy_strncmp(const char s1, const char s2,int n)

  • 1.在s1和s2所指向的字符串中,分别取出一个字符进行比较;
  • 2.判断这两个字符的ASCII码值大小,如果它们的值相等,那么返回第一步,比较下一个字符;否则,进入下一步;
  • 3.返回这两个字符的ASCII码差值;
  • 4.重复步骤1到3,直到满足下面两个条件中的任何一个条件为止。
    • 条件一:取出的字符是s1或者s2的小尾巴;
    • 条件二:已经比较了n个字符;

下面是我写的代码,请大家参考:

int diy_strncmp(const char *s1, const char * s2,int n)
{
    int res = 0;

    if(NULL == s1 || NULL == s2)
    {
        printf("NULL pointer error \n");
        return 0 ;
    }

    while(n)
    {
        if(*s1 != ‘\0‘ && *s2 != ‘\0‘)
        {
            if(*s1 == *s2)
            {
                s1++;
                s2++;
                n--;
            }
            else
            {
                res = *s1 -*s2;
                break;
            }
        }
        else
            break;
    }

    if(n > 0) // diffenent conditions
        res = *s1 -*s2; // the ASCII value of \0 is 0

    return res;
}

通过上面的代码,大家可以看到strncmp在比较过程中增加了对n的判断,如果n小于s1或者s2中的字符数量时,比较过程和strcmp相同,否则需要再计算一次比较结果,也就是代码中“if(n>0)” 这种情况。

下面是标准库中strncmp的代码,请大家和我们DIY的代码进行比较:

/**
 * strncmp - Compare two length-limited strings
 * @cs: One string
 * @ct: Another string
 * @count: The maximum number of bytes to compare
 */
int strncmp(const char *cs, const char *ct, size_t count)
{
        unsigned char c1, c2;

        while (count) {
                c1 = *cs++;
                c2 = *ct++;
                if (c1 != c2)
                        return c1 < c2 ? -1 : 1;
                if (!c1)
                        break;
                count--;
        }
        return 0;
}

通过对比,大家可以看到标准库提供的代码更加简洁一些,不过比较的思路是相同的。在返回结果中,标准库中的代码只返回-1,1和0这三种值。而我们DIY的代码中返回值与字符串中的字符有关,当然了,两个字符串相等时仍然返回1。

看官们,我把这两个DIY函数整理成了一个文件,并且添加了详细的注释,除此之外,我还使用了前面章回中的测试case进行测试。正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击这里下载使用。前面章回中的程序可以点击这里下载。

下面是程序运行的结果,请大家和前面章回中的程序运行结果进行对比。

 ----------- testing diy_strcmp -----------
abcd < abdc
abcd > ABCD
abcd > abc
abcd = abcd
 ----------- testing diy_strncmp -----------
3 of abcd < abdc
2 of abcd = abdc
2 of abcd > ABCD
5 of abcd > abc 

各位看官,关于DIY字符串比较函数的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解。


时间: 2024-10-23 22:58:17

一起talk C栗子吧(第六十六回:C语言实例--DIY字符串比较函数)的相关文章

一起talk C栗子吧(第十二回:C语言实例--单链表一)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们没有说具体的例子,而且是说了例子中的文件组织结构.这一回咱们继续说C例子, 说的例子是链表,更准确的说法叫作单链表.咱们不但要说C例子,而且会在例子中使用上一回中说过的 文件组织结构,就当作是举例说明文件组织结构的使用方法. 有点一石二鸟的感觉,哈哈. 链表定义 看官们,所谓的链表其实就是一组元素通过一定的方式链接在一起.比如我们坐的火车

一起talk C栗子吧(第一百六十二回:C语言实例--套接字知识体系图)

各位看官们,大家好,上一回中咱们说的是套接字通信模型的例子,这一回咱们说的例子是:套接字知识体系图.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们, 我们在前面的章回中介绍了许多关于套接字的内容,有些看官感觉知识比较乱,不断地摇头叹气,而且还在吟诗:剪不断,理还乱,是离愁.不对,是套接字.别有一番滋味在心头.哈哈.这位看官太有才了呀,连古诗也用上了.今天我和大家一起整理下套接字的知识,到时候将会是一番喜悦的滋味在心头. 看官们,我们最开始介绍的是套接字的概念,接着介绍了套接字的属性,

一起talk C栗子吧(第二十二回:C语言实例--队列一)

各位看官们,大家好,上一回中咱们说的是表达式求值的例子,该例子使用了栈,这一回咱们说的是栈的 兄弟:队列.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在这里说的队列是一种抽象的数据结构,大家不用想的太抽象了,哈哈,其实它和我们日常生活中所 见的队列一样.不管怎么样,我们还是举一个容易理解的例子:大家在假期出去旅游的时候,都有过排队 买门票的经历吧.游客们在售票点的窗口前排成了一长串队列,售票人员先把门票卖给排在队列前面的游 客,买到门票的游客拿着门票兴高采烈地离开了队列,刚来到售票点

一起talk C栗子吧(第一百六十九回:C语言实例--再谈内置宏)

各位看官们,大家好,上一回中咱们说的是C语言中的布尔–bool类型的例子,这一回咱们说的例子是:再谈内置宏 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在第一百二十四回中介绍了C语言中的内置宏,当时介绍了常用的内置宏_LINE_和_FILE_.并且介绍了如何使用它们来输出它们所在位置的行号和所在的文件名.大家都知道,这两个内置宏经常被用来在文件中添加调试信息.因为我们写的程序难免会有错误,所以需要对程序进行调试.在文件中加入内置宏后,我们通过调试可以快速地找到错误发生在哪个

一起talk C栗子吧(第十六回:C语言实例--栈一)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是双向链表的例子,这一回咱们说的例子是:栈. 什么是栈?我们听过龙门客栈,你这个是哪家客栈?我还没有说,台下已经有客官在问了.看官们,栈是 类似我们在前面几回中说过的链表,它也是用来存放数据的一种抽象的数据结构.因为比较抽象,咱们还 是举个现实生活中的例子来说明吧. 我们出去旅游时通常会拿一个行李箱存放自己的物品,比如衣服,鞋子电脑,

一起talk C栗子吧(第十八回:C语言实例--输出十六进制)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是栈的例子,这一回咱们说的例子是:输出十六进制. 看官们,我想熟悉C语言的朋友们,对于输出十六进制的内容,肯定都会使用printf函数进行格式化输出. 不过,有时候想输出十六进制时就会有点"不识庐山真面目,只缘身在此山中"的感觉.我在前面的例子中 有一个关于进制转换的例子.当时输出十六进制时使用分别判断10到15,然后依据判

一起talk C栗子吧(第十五回:C语言实例--双向链表)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是循环链表的例子,这一回咱们说的例子是:双向链表. 看官们,双向链表也是一种链表.我们在前面两回中说到的链表,都是沿着链表头部到链表尾部这样的方 向进行操作,而今天咱们要说的双向链表既可以沿着链表头部到链表尾部这样的方向进行操作,也可以沿 着链表尾部到链表头部这样的方向进行操作.这也是正是叫它双向链表的原因. 在例子中,查找和删除结点

一起talk C栗子吧(第十四回:C语言实例--循环链表)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是单链表链式存储列的例子,这一回咱们说的例子是:循环链表. 看官们,循环链表也是链表的一种,只不过该链表的头部和尾部相连接,所以构成了一个循环链,因此叫 作循环链表.让我们一起对比一下单链接与循环链表的不同之处:单链表的尾结点哪里也没有指,因为它 的next指针值为空.循环链表的尾结点指向了它的头结点. 看官们,正文中就不写代码了,详

一起talk C栗子吧(第一百六十八回:C语言实例--C语言中的布尔--bool类型)

各位看官们,大家好,上一回中咱们说的是控制终端字符颜色的例子,这一回咱们说的例子是:C语言中的布尔–bool类型 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,在数字电路中我们经常会遇到布尔类型,其实在编写软件的过程中也会使用布尔类型.布尔类型的变量只有两种值:真和假.在实际的编程过程中,我们经常定义宏,然后使用1表示真,0表示假.下面是具体的例子: #define TRUE 1 #define FALSE 0 例子中定义了两个宏,一个是TRUE,它的值是1,表示真:另外一个是F