赶紧来修炼内功~字符串函数详解大全(三)
目錄
1. strstr
2. strtok
重點(diǎn):?
?3. strerror
perror:
1. strstr
該函數(shù)是用來(lái)查找str1字符串中是否含有str2字符串
? ?存在:返回str2字符串所在的起始地址
不存在:返回NULL
int main() {char str1[] = "abcdefabc";char str2[] = "fab";char* p = strstr(str1, str2); //strstr函數(shù)的返回值為char*類型,所以創(chuàng)建一個(gè)char*類型的p來(lái) //接收地址printf("%s\n", p);return 0; }?如果str1字符串中含有多個(gè)str2字符串,那么返回第一次找到的str2的地址
int main() {char str1[] = "cdefabcfabfabdef";//含有多個(gè)"fab"字符串char str2[] = "fab";char* p = strstr(str1, str2);printf("%s\n", p);return 0; }?找不到就是不存在,返回NULL
int main() {char str1[] = "cdefadbc";char str2[] = "fab";char* p = strstr(str1, str2);if (p == NULL)printf("不存在\n");elseprintf("%s\n", p);return 0; }模擬實(shí)現(xiàn):
?創(chuàng)建一個(gè)my_strstr函數(shù),模擬實(shí)現(xiàn)strstr函數(shù)的功能:
char* my_strstr(const char* str1, const char* str2) { //通過(guò)4指針?lè)▽?shí)現(xiàn)assert(str1 && str2);char* s1 = str1;char* s2 = str2;while (*s1++ != '\0'){while (*s1 != *s2 && *s1 != '\0')s1++;str1 = s1;while (*s1 == *s2){s1++;s2++;}if (*s2 == '\0')return str1;s1 = str1;s2 = str2;}return NULL; } int main() {char arr1[] = "abcdefabcab";char arr2[] = "fabc";char* p = my_strstr(arr1, arr2);if (p == NULL)printf("不存在\n");elseprintf("%s\n", p);return 0; }2. strtok
該函數(shù)的返回類型為char*類型,
delimiters參數(shù)是個(gè)字符串,定義了用作分隔符的字符集合,
第一個(gè)參數(shù)指定一個(gè)字符串,它包含了0個(gè)或者多個(gè)由delimiters字符串中一個(gè)或者多個(gè)分隔符分割的標(biāo)記。
該函數(shù)的作用是:將str所指向的字符串按分隔符分割成若干段字符串。
重點(diǎn):?
1. strtok函數(shù)找到str中的下一個(gè)標(biāo)記,并將其用 '\0' 結(jié)尾,返回一個(gè)指向這個(gè)標(biāo)記起始位置的指針。(注: strtok函數(shù)會(huì)改變被操作的字符串,所以在使用strtok函數(shù)切分的字符串一般都是臨時(shí)拷貝的內(nèi)容 并且可修改。)
2. strtok函數(shù)的第一個(gè)參數(shù)不為 NULL ,函數(shù)將找到str中第一個(gè)標(biāo)記,strtok函數(shù)將保存它在字符串中的位置。
3. strtok函數(shù)的第一個(gè)參數(shù)為 NULL ,函數(shù)將在同一個(gè)字符串中被保存的位置開(kāi)始,查找下一個(gè)標(biāo)記。
4. 如果字符串中不存在更多的標(biāo)記,則返回 NULL 指針。
int main() {char* p = "shandongkejidaxue@985.com";const char* del = ".@";char arr[30];strcpy(arr, p);//將數(shù)據(jù)拷貝一份,處理arr數(shù)組的內(nèi)容char* str = strtok(arr, del);printf("%s\n", str); }以上面這段代碼為例:
將p所指向的字符串拷貝到arr中,將arr傳給strtok函數(shù),再傳分隔符的字符串del,這樣函數(shù)就會(huì)找arr字符串中有沒(méi)有del中的字符,將找到的第一個(gè)標(biāo)記改為'\0',這里找到的第一個(gè)標(biāo)記就是'@',并返回指向這個(gè)標(biāo)記起始位置的指針,這里我們用str接收,然后以str為指針打印字符串,就得到了"shandongkejidaxue"。
此時(shí),我們要是想繼續(xù)打印接下來(lái)分割的字符串,還需要再用一次strtok函數(shù),不過(guò)這次我們第一個(gè)參數(shù)就直接給NULL就行,因?yàn)楫?dāng)strtok函數(shù)的第一個(gè)參數(shù)不為 NULL ,函數(shù)將找到str中第一個(gè)標(biāo)記,strtok函數(shù)將保存它在字符串中的位置,我們上一次用strtok函數(shù)時(shí),他已經(jīng)保存了第一個(gè)標(biāo)記的位置,所以我們第二次使用strtok函數(shù)時(shí)第一個(gè)參數(shù)傳NULL,這時(shí)strtok函數(shù)的第一個(gè)參數(shù)為 NULL ,函數(shù)將在同一個(gè)字符串中被保存的位置開(kāi)始,查找下一個(gè)標(biāo)記,這樣一來(lái),就可以繼續(xù)分割后面的字符串了。以此類推,第三次、第四次均是如此~
int main() {char* p = "shandongkejidaxue@985.com";const char* del = ".@";char arr[30];strcpy(arr, p);//將數(shù)據(jù)拷貝一份,處理arr數(shù)組的內(nèi)容char* str = strtok(arr, del);printf("%s\n", str);str = strtok(NULL, del);printf("%s\n", str);str = strtok(NULL, del);printf("%s\n", str);}當(dāng)我們不知道所要分割的字符串中含有多少個(gè)分隔符時(shí),我們可以用循環(huán)來(lái)實(shí)現(xiàn)?
#include <stdio.h> int main() {char* p = "shandongkejidaxue@985.com";const char* del = ".@";char arr[30];char* str = NULL;strcpy(arr, p);//將數(shù)據(jù)拷貝一份,處理arr數(shù)組的內(nèi)容for (str = strtok(arr, del); str != NULL; str = strtok(NULL, del)){//如果字符串中不存在更多的標(biāo)記,則返回 NULL 指針,所以當(dāng)str為NULL時(shí)就說(shuō)明字符串已經(jīng)分割完 //成了。printf("%s\n", str);} }?3. strerror
參數(shù)為錯(cuò)誤碼
返回值為錯(cuò)誤碼所對(duì)應(yīng)的錯(cuò)誤信息
這里的0、1、2、3、4均為錯(cuò)誤碼,一個(gè)錯(cuò)誤碼對(duì)應(yīng)一個(gè)錯(cuò)誤信息。
?那么怎么用這個(gè)函數(shù)呢?
這里舉一個(gè)例子:
//errno 為C語(yǔ)言提供的全局的錯(cuò)誤碼變量,將錯(cuò)誤碼記錄到該變量中 //頭文件為 <errno.h> #include <errno.h> int main() {//打開(kāi)一個(gè)文件并讀取FILE* pf = fopen("test.txt", "r");if (pf == NULL)//若為NULL表示打開(kāi)失敗{printf("%s\n", strerror(errno));}else{//讀文件//關(guān)閉文件fclose(pf);pf = NULL;}return 0; }?表示沒(méi)有找到該文件,即該文件不存在。
perror:
這里還有一個(gè)函數(shù)與strerror函數(shù)相似:
perror? ? ? ? ? ? ? ? ? (頭文件為? <stdio.h>)
int main() {//打開(kāi)一個(gè)文件并讀取FILE* pf = fopen("test.txt", "r");if (pf == NULL)//若為NULL表示打開(kāi)失敗{perror("fopen");//內(nèi)容可以根據(jù)需要隨意更改~}else{//讀文件//關(guān)閉文件fclose(pf);pf = NULL;}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的赶紧来修炼内功~字符串函数详解大全(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Windows:忘记本地账户开机密码,但
- 下一篇: 用ps制作android日历步骤,绘制一