目錄
查找一個字元
查找任何幾個字元
查找一個字串
strrstr的自定義編寫實踐
strrpbrk的自定義編寫實踐
标準庫中有很多函數,它們用各種不同的方法查找字元串。下面分别介紹:
先介紹标準庫中有的,之後再擴充标準庫中沒有的。
在一個字元串中查找一個特定字元分為兩種情況:第一是查找特定字元第一次出現的字元,第二種是查找特定字元最後一次出現的字元。
分别對應的函數是:strchr 和 strrchr函數,它們的原型如下:
char *strchr( char const *str, int ch );
char *strrchr( char const *str, int ch);
注意第2個參數是一個整型值。(每個字元都會對應一個ASCII碼,ASCII碼是一個整形數值。)
strchr在字元串str中查找字元ch第1次出現的位置,找到後函數傳回一個指向該位置的指針。如果該字元并不存在于字元串中,函數就傳回一個NULL指針。strrchr函數名和strchr相比,多了一個字母r,代表“right”,也就是它傳回的是一個指向字元串中該字元最後一次出現的位置(最右邊那個),後面的函數出現r時,意義都是這樣。
舉個例子:
char string[20] = "Hello there, honey.";
char *ans;
ans = strchr( string, 'h' );
ans所指向的位置将是 string + 7,因為第1個'h'出現在這個位置。注意這裡大小寫是有差別的。
strpbrk是個更為常見的函數。它并不是查找某個特定的字元,而是查找任何一組字元第1次在字元串中出現的位置。它的原型如下:
char *strpbrk( char const *str, char const *group );
這個函數傳回一個指向str中第1個比對group中任何一個字元的字元位置。如果未找到比對,函數傳回一個NULL指針。
在下面的代碼段中,
ans = strpbrk( string, "aeiou" );
ans所指向的位置是string + 1,因為這個位置是第2個參數中的字元第一次出現的位置。
為了在字元串中查找一個字串,我們可以使用strstr函數,它的原型如下:
char *strstr( char const *s1, char const *s2 );
這個函數在s1中查找整個s2第一次出現的位置,并傳回一個指向該位置的指針。如果s2沒有完整地出現在s1的任何地方,函數将傳回一個NULL指針。如果第二個參數是一個空字元串,就傳回s1.
注意,标準庫中并不存在strrstr或strrpbrk函數。不過,如果你需要它們,它們可以很容易實作。下面給出一個實作strrstr的方法:
查找字串最右一次出現的位置:
//在字元串s1中查找字元串s2最右出現的位置,并傳回一個指向該位置的指針
#include<string.h>
char * my_strrstr(char const *s1, char const *s2)
{
register char *last;
register char *current;
last = NULL;
//隻有第2個字元串不為空時才進行查找,如果s2為空,則傳回NULL
if(*s2 != '\0')
{
//查找s2在s1中的位置
current = strstr( s1, s2 );
//我們每次找到字元串時,讓指針指向它的起始位置,然後查找該字元串下一個比對位置
while(current != NULL)
{
last = current;
current = strstr(last + 1, s2); //從上次查找到的比對字元串的位置繼續開始繼續查找
}
}
//傳回指向我們找到的最後一次比對的起始位置的指針
return last;
}
下面我們繼續編寫一個strrpbrk的程式,查找任何幾個字元在字元串中最後出現的位置:
//在字元串s1中查找字元組中最右出現的位置,并傳回一個指向該位置的指針
#include <string.h>
char * my_strrpbrk(char const *str, char const *group)
{
register char *last;
register char *current;
last = NULL;
//隻有第2個group不為空時才進行查找,如果s2為空,則傳回NULL
if(*group != '\0')
{
//查找group中字元在str中的位置
current = strpbrk( str, group );
//我們每次找到比對字元時,讓指針指向它的起始位置,然後查找該字元下一個比對位置
while(current != NULL)
{
last = current;
current = strpbrk(last + 1, group); //從上次查找到的比對字元的位置繼續開始繼續查找
}
}
//傳回指向我們找到的最後一次比對的起始位置的指針
return last;
}
是不是和上面的那個很相似呢?确實如此!
隻是改好了還不夠有說服力,那就實際應用下看看,結果是否如意:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *my_string = "Soul Da, how is everything going?"; //在這個字元串中查找目标字元
char *aim_string = "aeiou"; //需要查找的字元
char *p; //用來接收函數傳回的指針
//函數原型
char *my_strrpbrk(char const *str, char const *group);
//調用函數
p = my_strrpbrk(my_string, aim_string);
printf("%s\n", p);
return 0;
}
//定義函數my_strrbprk
char *my_strrpbrk(char const *str, char const *group)
{
register char *last;
register char *current;
last = NULL;
//隻有第2個group不為空時才進行查找,如果s2為空,則傳回NULL
if(*group != '\0')
{
//查找group中字元在str中的位置
current = strpbrk( str, group );
//我們每次找到比對字元時,讓指針指向它的起始位置,然後查找該字元下一個比對位置
while(current != NULL)
{
last = current;
current = strpbrk(last + 1, group); //從上次查找到的比對字元的位置繼續開始繼續查找
}
}
//傳回指向我們找到的最後一次比對的起始位置的指針
return last;
}
在codeblock中運作的結果為:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CO3UTMyUjYlVzYhJzNhdjM4QDOiVTOkZTY4UjZilzMk9CXwIzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL5M3Lc9CX6MHc0RHaiojIsJye.png)
和預想的一樣。
最後我提醒一下,這個程式在C++中竟然運作不出來,老是報錯,并不是頭檔案的問題,頭檔案我也添加了C++中需要的。不管了,等到開始C++學習後再試試哪裡出問題了。
還要提醒一點呢?就是函數的名字比較難記,别寫錯了,例如strpbrk寫成了strbprk,因為這個問題我也是很郁悶,最後才發現我拼寫出問題了。哈哈,可能是菜吧!