【字符串】字符串查找函數詳解


在對 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\n", lc);
6     char *rc = strrchr(str, 'o');
7     printf("strrchr: %s\n", 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('\0') 不包括在內,若找不到則返回空指針。其函數原型的一般格式如下:

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

例如,在 strpbrk 函數的定義如下:

 1 char *strpbrk (const char *s, const char *accept)
 2 {
 3     while (*s != '\0')
 4     {
 5         const char *a = accept;
 6         while (*a != '\0')
 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('\0')不包括在內。函數的調用示例如下面的代碼所示:

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\n",rc);
6     return 0;
7 }

使用 strstr 函數查找一個子串

相對於 strpbrk 函數,strstr 函數表示在字符串 haystack 中從前到后查找子串 needle 第一次出現的位置(不比較結束符 null('\0')),並返回指向第一次出現 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 != '\0'; ++p)
 7     {
 8         for (a = accept; *a != '\0'; ++a)
 9             if (*p == *a)
10                 break;
11             if (*a == '\0')
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\n",strspn(str,"I wel"));
5     printf("Iwel:%d\n",strspn(str,"Iwel"));
6     printf("welcome:%d\n",strspn(str,"welcome"));
7     printf("5:%d\n",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 != '\0')
 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\n",strcspn(str,"I wel"));
5     printf("Iwel:%d\n",strcspn(str,"Iwel"));
6     printf("welcome:%d\n",strcspn(str,"welcome"));
7     printf("5:%d\n",strcspn(str,"5"));
8     return 0;
9 }

在上面的示例代碼中,因為 strcspn 函數返回的是以字符串 s 開頭連續不包含字符串 accept 內的字符數目。

由此可見,對於 strspn 函數,如果找到了 reject 與 s 不相同元素時,指針停止移動,並返回以字符串 s 開頭連續包含字符串 accept 內的字符數目;而 strncspn 函數則是找到了 reject 與 s 相同元素時,指針停止移動,並返回以字符串 s 開頭連續不包含字符串 accept 內的字符數目。這一點一定要注意,千萬不要混淆了。
 
 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM