[C] 每天來點字串用法 (4) - strchr()、strrchr()、strstr()
不知道這次有沒有拖到,blogger 自帶的時間搞得我好混亂啊ˊˇˋ
進入正題,今天要講的是:
函式宣告:
這兩個函式還滿簡單的,比較需要注意的地方是:由於回傳的是第一個 ch 出現的地方,所以如果要繼續找第二、三...個的話,要從「回傳的位址 +1」開始。 另外,如果你想找 '\0' 這個字元的話也是可以的,反正一個字串一定會有一個 '\0' 嘛。
我們可以看看下面的範例:給定一個 DNA 序列,把其中的 'T' 全部換成 'U',使其成為合法的 RNA 序列。(轉錄什麼的不重要啦 XD)
這次還要介紹另一個函式:strstr(),詳細如下。
函式宣告:
直接看範例吧:在一串 RNA 序列中找到起始密碼子 "AUG",並輸出只留下 "AUG" 以及其後剩餘的 RNA 序列。
參考資料:
1-3) cppreference - strchr、cppreference - strrchr、cppreference - strstr
4) 我的腦袋
進入正題,今天要講的是:
- strchr()、strrchr():字串中搜尋字元
函式宣告:
char *strchr( const char *str, int ch );
char *strrchr( const char *str, int ch );
先傳入一個字串 str,再傳入一個字元 ch(雖然宣告裡它的型態是 int,但 char 本來就是用 ASCII 碼存的,所以傳入後會被當成整數來使用),如果有在 str 裡找到 ch,回傳第一個 ch 的所在位址;如果找不到,回傳 NULL。 而這兩個函式的差別在於:strchr()是從前面開始找 ch,而 strrchr() 則是從後面開始找。這兩個函式還滿簡單的,比較需要注意的地方是:由於回傳的是第一個 ch 出現的地方,所以如果要繼續找第二、三...個的話,要從「回傳的位址 +1」開始。 另外,如果你想找 '\0' 這個字元的話也是可以的,反正一個字串一定會有一個 '\0' 嘛。
我們可以看看下面的範例:給定一個 DNA 序列,把其中的 'T' 全部換成 'U',使其成為合法的 RNA 序列。(轉錄什麼的不重要啦 XD)
#include <stdio.h>
#include <string.h>
int main(){
char s1[16];
scanf("%s", s1); // 可以輸入 ATAGCTACTG 看看
char *ptr = s1;
while (ptr != NULL){
ptr = strchr(s1, 'T');
if (ptr){
*ptr = 'U'; // 取得或修改 ptr 指到的字元
}
}
printf("%s\n", s1); // 輸出 AUAGCUACUG
return 0;
}
這裡的 highlight 有點雜,希望看了不會眼花。要標那麼多行主要是想再多介紹一些字串用法,首先是第 8 和 10 行,因為 NULL 的值是 0,所以我們可以利用 C 的特性:非零數值皆為真,只有 0 為假,來進行判斷式的簡化,也就是說,當start、ptr 並不是指向 NULL 時,就會回傳真,代表有東西要處理,反之回傳假,代表可以結束了。 其次是行 11,如果我們使用「*」來對指向字串的字元指標取值,就會只取到開頭的第一個字元,而我們也可以對其修改,把其他字元指定給它。這次還要介紹另一個函式:strstr(),詳細如下。
- strstr():字串中搜尋字串
函式宣告:
char *strstr( const char* str, const char* substr );
這個函式會在 str 中尋找 substr,一樣回傳 substr 的第一個出現位址,如果沒找到的話則是 NULL。直接看範例吧:在一串 RNA 序列中找到起始密碼子 "AUG",並輸出只留下 "AUG" 以及其後剩餘的 RNA 序列。
#include <stdio.h>
#include <string.h>
int main(){
char s1[32];
scanf("%s", s1); // ACUGCUAUGCUACAGUG
char *ptr = strstr(s1, "AUG");
if (ptr){
printf("%s\n", ptr); // AUGCUACAGUG
}
return 0;
}
- Undefined Behavior
參考資料:
1-3) cppreference - strchr、cppreference - strrchr、cppreference - strstr
4) 我的腦袋
留言
張貼留言