• 【字符串】字符串查找函数详解


    在对 C 语言的编程实践中,字符串查找是最频繁的字符串操作之一,本节就对常用的字符串查找函数做一个简单的总结。

    使用 strchr 与 strrchr 函数查找单个字符

     如果需要对字符串中的单个字符进行查找,那么应该使用 strchr 或 strrchr 函数。其中,strchr 函数原型的一般格式如下:

    1 char *strchr(const char*s,int c);

    它表示在字符串 s 中查找字符 c,返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL。也就是说,strchr 函数在字符串 s 中从前到后(或者称为从左到右)查找字符 c,找到字符 c 第一次出现的位置就返回,返回值指向这个位置,如果找不到字符 c 就返回 NULL。

    相对于 strchr 函数,strrchr 函数原型的一般格式如下:

    1 char *strrchr(const char*s,int c);

     与 strchr 函数一样,它同样表示在字符串 s 中查找字符 c,返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL。但两者唯一不同的是,strrchr 函数在字符串 s 中是从后到前(或者称为从右向左)查找字符 c,找到字符 c 第一次出现的位置就返回,返回值指向这个位置。下面的示例代码演示了两者之间的区别:

    1 int main(void)
    2 {
    3     char str[] = "I welcome any ideas from readers, of course.";
    4     char *lc = strchr(str, 'o');
    5     printf("strchr: %s
    ", lc);
    6     char *rc = strrchr(str, 'o');
    7     printf("strrchr: %s
    ", rc);
    8     return 0;
    9 }

    对于上面的示例代码,strchr 函数是按照从前到后的顺序进行查找,所以得到的结果为“ome any ideas from readers,of course.”; 而 strrchr 函数则相反,它按照从后到前的顺序进行查找,所以得到的结果为“ourse.”。

    最后还需要注意的是,为什么函数的“c”参数是 int 类型,而不是“char”类型呢?

    其实原因很简单,这里用的是字符的 ASCII 码(因为每个字符都对应着一个 ASCII 码),这样在传值的时候既可以传“char”类型的值,又可以传“int”类型的值(0~127)。

    使用 strpbrk 函数查找多个字符

    上面的 strchr 与 strrchr 函数解决了对字符串中单个字符的查找,那么需要查找多个字符时怎么办呢?

    如果要查找多个字符,就需要使用 strpbrk 函数了。该函数在源字符串(s1)中按从前到后顺序找出最先含有搜索字符串(s2)中任一字符的位置并返回,空字符 null('') 不包括在内,若找不到则返回空指针。其函数原型的一般格式如下:

    1 char *strpbrk(const char *s1,const char*s2);

    例如,在 strpbrk 函数的定义如下:

     1 char *strpbrk (const char *s, const char *accept)
     2 {
     3     while (*s != '')
     4     {
     5         const char *a = accept;
     6         while (*a != '')
     7             if (*a++ == *s)
     8                 return (char *) s;
     9         ++s;
    10     }
    11     return NULL;
    12 }

    如上面的代码所示,strpbrk 数首先依次循环检查字符串 s 中的字符,当被检验的字符在字符串 accept 中也包含时(即“if(*a++==*s)”),则停止检验,并返回“(char*)s”。如果没有匹配字符,则返回空指针 NULL。这里需要注意的是,空字符 null('')不包括在内。函数的调用示例如下面的代码所示:

    1 int main(void)
    2 {
    3     char str[] = "I welcome any ideas from readers, of course.";
    4     char *rc=strpbrk(str,"come");
    5     printf("%s
    ",rc);
    6     return 0;
    7 }

    使用 strstr 函数查找一个子串

    相对于 strpbrk 函数,strstr 函数表示在字符串 haystack 中从前到后查找子串 needle 第一次出现的位置(不比较结束符 null('')),并返回指向第一次出现 needle 位置的指针,如果没找到则返回 NULL。其函数原型的一般格式如下:

    1 size_t strspn(const char *s, const char *accept);

    例如,该函数的定义如下:

     1 size_t strspn (const char *s,const char *accept)
     2 {
     3     const char *p;
     4     const char *a;
     5     size_t count = 0;
     6     for (p = s; *p != ''; ++p)
     7     {
     8         for (a = accept; *a != ''; ++a)
     9             if (*p == *a)
    10                 break;
    11             if (*a == '')
    12                 return count;
    13             else
    14                 ++count;
    15     }
    16     return count;
    17 }

    从上面的示例代码中可以看出,strspn 函数从字符串参数 s 的开头计算连续的字符,而这些字符完全是 accept 所指字符串中的字符。简单地说,如果 strspn 函数返回的数值为 n,则代表字符串 s 开头连续有 n 个字符都属于字符串 accept 内的字符。

    函数的调用示例如下面的代码所示:
    1 int main(void)
    2 {
    3     char str[] = "I welcome any ideas from readers, of course.";
    4     printf("I wel:%d
    ",strspn(str,"I wel"));
    5     printf("Iwel:%d
    ",strspn(str,"Iwel"));
    6     printf("welcome:%d
    ",strspn(str,"welcome"));
    7     printf("5:%d
    ",strspn(str,"5"));
    8     return 0;
    9 }

    在上面的示例代码中,因为 strspn 函数返回的是以字符串 s 开头连续包含字符串 accept 内的字符数目。而源字符串 str 中的“I”与“welcome”之间有一个空格(即“I welcome”),所以,语句“strspn(str,"Iwel")”将返回 1,而语句“strspn(str,"I wel")”将返回 5。因此,输出结果为:

    相对于 strspn 函数,strcspn 函数与之相反,它表示从字符串 s 第一个字符开始,逐个检查字符与 reject 中的字符是否相同,如果相同,则停止检查,并返回以字符串 s 开头连续不含字符串 reject 内的字符数目。其函数原型的一般格式如下:

    1 size_t strcspn(const char *s, const char *reject);

    该函数的定义如下:

     1 size_t strcspn (const char *s,const char *reject)
     2 {
     3     size_t count = 0;
     4     while (*s != '')
     5         if (strchr (reject, *s++) == NULL)
     6             ++count;
     7         else
     8             return count;
     9     return count;
    10 }

    从上面的代码中不难发现,strcspn 函数正好与 strspn 函数相反。strcspn 函数从字符串参数 s 的开头计算连续的字符,而这些字符都完全不在参数 reject 所指的字符串中。简单地说,如果 strcspn 函数返回的数值为 n,则代表字符串 s 开头连续有 n 个字符都不包含字符串 reject 内的字符。

    函数的调用示例如下面的代码所示:

    1 int main(void)
    2 {
    3     char str[] = "I welcome any ideas from readers, of course.";
    4     printf("I wel:%d
    ",strcspn(str,"I wel"));
    5     printf("Iwel:%d
    ",strcspn(str,"Iwel"));
    6     printf("welcome:%d
    ",strcspn(str,"welcome"));
    7     printf("5:%d
    ",strcspn(str,"5"));
    8     return 0;
    9 }

    在上面的示例代码中,因为 strcspn 函数返回的是以字符串 s 开头连续不包含字符串 accept 内的字符数目。

    由此可见,对于 strspn 函数,如果找到了 reject 与 s 不相同元素时,指针停止移动,并返回以字符串 s 开头连续包含字符串 accept 内的字符数目;而 strncspn 函数则是找到了 reject 与 s 相同元素时,指针停止移动,并返回以字符串 s 开头连续不包含字符串 accept 内的字符数目。这一点一定要注意,千万不要混淆了。
     
     

     

     

     

  • 相关阅读:
    二分查找递归和非递归版
    git常用命令记录
    总结下本周所学的建站流程极其经验
    Ubuntu下su命令失败的解决方法,及其环境变量失效解决
    ubuntu下node安装的三种方法
    Markdown学习及如何在博客园中使用
    nmcli使用方法
    Elasticsearch 升级 7.x 版本后,我感觉掉坑里了!
    Spring Data Elasticsearch基本操作自定义查询
    ElasticSearch——聚合
  • 原文地址:https://www.cnblogs.com/Luthais/p/10237077.html
Copyright © 2020-2023  润新知