大家好呀,今天給大家分享一下字符函數和字符串函數,說起字符函數和字符串函數大家會想到哪些呢??我想到的只有求字符串長度的strlen,拷貝字符串的strcpy,字符串比較相同的strcmp,今天,我要分享給大家的是我們一些其他的字符函數和字符串函數,跟著小張一起去看看吧!
文章目錄
- 前言
- 長度不受限制的字符串函數
- strcat
- 長度受限制的字符串函數
- strncpy
- strncat
- strncmp
- 字符串查找
- strstr
- strtok
- 錯誤信息報告
- strerror
- 模擬實現
- strcat的模擬實現
- strstr的模擬實現
- 總結
前言
C語言中對字符和字符串的處理很是頻繁,但是C語言本身是沒有字符串類型的,字符串通常放在 常量字符串中或者字符數組 中.字符串常量 適用于那些對它不做修改的字符串函數
長度不受限制的字符串函數
strcat
功能:可以在一個字符串后面追加字符
函數聲明:char *strcat( char *strDestination, const char *strSource );
頭文件:string.h
參數解釋以及返回值解釋:第一個參數接收被追加字符串數組的地址,第二個參數是追加的內容字符串數組,返回的是追加后字符串數組的地址
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
#include <string.h>int main()
{char arr1[20] = "abcdef";char arr2[] = "gh";strcat(arr1, arr2);printf("%s", arr1);}
注意:源字符串必須以 ‘\0’ 結束。
目標空間必須有足夠的大,能容納下源字符串的內容。
目標空間必須可修改。
int main()
{char arr1[20] = "abcdef";char arr2[] = {'a','b','c'};strcat(arr1, arr2);printf("%s", arr1);
}
程序發生崩潰,arr2數組如果沒有’\0’的話,他會在后面地址上找到\0,在追加到arr1數組的時候,會越界放不下
字符串strcat函數不能自己給自己追加
追加前
追加后
追加的時候把源數組中的‘\0’被追加字符所覆蓋
長度受限制的字符串函數
strncpy
功能:拷貝num個字符從源字符串到目標空間
函數聲明:char * strncpy ( char * destination, const char * source, size_t num );
頭文件:string.h
參數:第一個參數為接收目標空間地址,第二個參數接收是源空間地址,返回參數是目標地址,size_t是無符號整數類型,num是拷貝字符的數目
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
#include <string.h>int main()
{char arr1[40] = "hered ";char arr2[] = "ll";strncpy(arr1,arr2,2);printf("%s",arr1);
}
如果源字符小于要拷貝的個數會怎么樣??
int main()
{char arr1[40] = "hered+++++++++ ";char arr2[] = "ll";strncpy(arr1, arr2, 10);printf("%s", arr1);
}
注意:拷貝num個字符從源字符串到目標空間。
如果源字符串的長度小于num,則拷貝完源字符串之后,在目標的后邊追加0,直到num個。
strncat
功能:追加num個字符從源字符串到目標空間。
聲明:char * strncat ( char * destination, const char * source, size_t num );
頭文件:string.h
參數:第一個參數為接收目標空間地址,第二個參數接收是源空間地址,返回參數是目標地址,size_t是無符號整數類型,num是追加字符的數目
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{char arr1[40] = "hello ";char arr2[13] = "shuxiansheng";strncat(arr1, arr2, 3);printf("%s",arr1);
}
strncat可以追加自己
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{char arr1[40] = "hello ";char arr2[13] = "shuxiansheng";strncat(arr1, arr1, 5);printf("%s",arr1);
}
strncmp
功能:可以比較指定個數的字符串比較
聲明:int strncmp ( const char * str1, const char * str2, size_t num );
頭文件:string.h
參數:第一個參數接收第一個字符串地址,第二個參數接收第二個字符串地址,第三個參數為比較字符的個數,比較到出現另個字符不一樣或者一個字符串結束或者num個字符全部比較完。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{char arr1[6] = "hello";char arr2[] = "helld";int ret=strncmp(arr1, arr2, 4);printf("%d", ret);
}
比較前四個字符,由于前四個字符相同,返回0,比較五個字符,o的ascll碼值大于d的ascll碼值返回1;
字符串查找
strstr
功能:查找子串
聲明: char * strstr ( char * str1, const char * str2 );
頭文件string.h
參數:第一個參數接收被查找的字符串的首地址,第二個參數疑似子串的字符串的首地址
如果是子串的話,返回字符串中子串的首地址,不是子串的話返回空指針
代碼
int main()
{char arr1[] = "abcdefg";char arr2[] = "fg";char *p=strstr(arr1,arr2);//保存返回子串的首地址if (p){printf("是子串:%s", p);}else{printf("不是子串");}}
編譯運行
strtok
功能:分隔子串
聲明:char * strtok ( char * str, const char * sep );
頭文件:string.h
參數:第一個參數接收被分解字符串的地址,第二個參數中接收的是字符串中分隔符的地址,返回被分隔子串的首地址
代碼
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello@qq.com";char arr2[] = "@.";strtok(arr1, arr2);printf("%s", arr1);
}
編譯運行
第一個參數指定一個字符串,它包含了0個或者多個由arr2字符串中一個或者多個分隔符分割的標記。
strtok函數找到arr1中的下一個標記,并將其用 \0 結尾,返回一個指向這個標記的指針。
strtok函數的第一個參數不為 NULL ,函數將找到arr1中第一個標記,strtok函數將保存它在字符串中的位置(strtok函數在內部維護了一個靜態變量保存這個位置)。
strtok函數的第一個參數為 NULL ,函數將在同一個字符串中被保存的位置開始,查找下一個標記。
如果字符串中不存在更多的標記,則返回 NULL 指針
代碼展示
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello@qq.com";char arr2[] = "@.";printf("%s\n", strtok(arr1, arr2));printf("%s\n", strtok(NULL, arr2));printf("%s\n", strtok(NULL, arr2));}
編譯運行
修改:我們可以將字符串arr1傳給strtok函數,第一個@分隔符。strtok函數返回字符串中第一個遇到分隔符之前的字符串首地址,”hello’',然后在循環中繼續調用strtok函數,第一個參數傳NULL,strtok自己維護的靜態變量,記住上次分隔的地方,不用在傳arr1.
代碼實現
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello@qq.com";char arr2[] = "@.";char* p =NULL;for (p = strtok(arr1, arr2); p != NULL; p = strtok(NULL, arr2)){printf("%s\n",p);}}
編譯運行
錯誤信息報告
strerror
功能:可以返回指向錯誤信息字符串地址
聲明:char *strerror( int errnum );
頭文件:string.h errno.h
參數:errnum是錯誤碼,就像404頁面,每個錯誤碼對應著錯誤信息,返回值是指向錯誤信息字符串地址
int main()
{printf("%s\n", strerror(0));printf("%s\n", strerror(1));printf("%s\n", strerror(2));printf("%s\n", strerror(3));}
當我們向內存申請空間時,我們會使用malloc函數,如果申請的內存太大,是否會報錯呢??它會將錯誤碼放在整型全局變量errno中,使用errno時引用頭文件errno.h
代碼展示:
`#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{int *p=malloc(4000000000);//malloc申請內存失敗會返回空地址if (p == NULL){printf("%s\n", strerror(errno));}}`
注意:遇到多個錯誤時,errno會不斷賦新的錯誤碼
模擬實現
strcat的模擬實現
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* mystrcat(char* p, char* q)
{assert(p && q);char* k = &p;//隨著p++,會丟失目標字符串首地址先保存while (*p){p++;}//將p指針移動到目標字符串'\0'位置while ((*p++=*q++))//將*q的值先給*p,然后兩個q++;p++;賦值后的ascll值不為0,繼續循環,當*q=='\0',賦值后ascll碼值為'\0',退出循環{}return k;//返回目標字符串首地址
}
int main()
{char arr1[20] = "abcde";char arr2[5] = "qqq";mystrcat(arr1, arr2);printf("%s", arr1);}
strstr的模擬實現
char* mystrstr(char* str1, char* str2)
{char* s1 = str1;//兩個遍歷指針分別指向兩個字符串的首地址char* s2 = str2;char* cur = s1;//兩個字符串開始匹配的指針while (*cur)//每循環一次,就是重新匹配的過程{s1 = cur;//s1移動到下一個開始匹配的位置s2 = str2;//子串要從頭開始匹配while (*s1&&*s2&&(*s1 == *s2))//匹配的循環{s1++;s2++;}//不匹配退出循環if (*s2 == '\0')//當匹配循環完,s2的指針指向子串的末尾'\0';{return cur;//保存的是匹配成功時,字符串中匹配到的第一個字符首地址}cur++; //此時cur指向的位置不能作為開始匹配的位置,cur++;開始新一輪的匹配}return NULL;//當cur遍歷完字符串,則說明沒有該子串
}
int main()
{char arr1[] = "abcdecdfg";char arr2[] = "cdf";char *p=mystrstr(arr1,arr2);//如果找到子串返回字符串中和子串匹配的首字符首地址不為空if (p){printf("是子串");}else{printf("不是子串");}}
編譯運行
總結
字符串函數,字符函數在處理字符問題特別的方便,使得問題簡單化,本章還未講到的內存操作函數放在下一篇講,如果你覺得這篇文章對你有幫助的話,別忘了給小張點贊,收藏加關注,哪里不對的話還望大佬們指教,謝謝大家!!我會持續分享給大家自己學到的知識,也是在好好的做總結