字符串處理函數
1.字符串長度 strlen表示包含的字符的個數,size_t strlen(char cosnt *string), 返回的是size_t類型,它是無符號整數類型,在表達式中進行運算時必須強制轉換成整型int,因為無符號數不可能是負的,如strlen(x) - strlen(y) >=0;
2.不受限制的字符串函數,只是通過尋找字符串參數結尾的NUL字節來判斷他的長度,必須保證不會溢出,strcpy和strcat返回第一個參數的拷貝,是一個指向目標字符數組的指針。
(1)復制字符串
char *strcpy(char *dst, char const *src),其中參數dst可以修改,因此它必須是字符數組或一個指向動態分配內存的數組指針,足夠大,提前開辟,不能自動計算數組長度,不能是字符串常量。新字符串以NUL結尾,如果新字符串比較短,老字符串后面的幾個字符也會被有效刪除。
(2)連接字符串
char *strcat(char *dst, char const *src),其中dst和src的內存位置不能出現交疊,即dst和src為同一個定義的字符串,另外需要保證不會溢出。
(3)字符串比較
char *strcmp(char const *s1, char const *s2),如果s1小於s2,strcmp返回一個小於零的值,如果大於0,返回大於0的值,如果相等返回0
3.長度受限制的字符串函數
(1)char *strncpy(char *dst, char const *src, size_t len);顯示接受一個長度參數,當src的字符串長度小於len,則dst用額外的NUL字節填充到len長度,如果src大於或等於len,dst的末尾不會以NUL結尾,因此考慮在函數后加一條語句:dst(sizeof(dst) - 1) = '\0';
(2)char *strncat(char *dst, char const *src, size_t len);總是在結果字符串后面添加一個NUL字節,不管dst的長度,最多往dst中復制len個字符,再加一個NUL字節。
1 char a[3] = "ab"; 2 char b[4] = "mnp"; 3 strncat(a, b, 3); 4 for (size_t i = 0; i < 10; i++) 5 printf("%c\n", a[i]);
總是在dst的末尾添加,不管dst的長度。
(3)char *strncmp(char const *s1, char const *s2, size_t len);函數的返回值只根據len個字節的比較來確定
4.字符串查找(重點)
(1)查找一個字符
char *strchr(char const *str, int ch);
char *strrchr(char const *str, int ch);
雖然第二個參數是整型值,但其實是一個字符值。分別返回ch在str中第一次出現和最后一次出現的位置,如果不存在則返回NULL指針。
1 #include <string.h> 2 #include <stdio.h> 3 int buld(char* str, char c) { 4 int p = strchr(str,c) - str; //??? 5 return p; 6 } 7 int main() { 8 char str1[20],c; 9 printf("輸入字符串:\n"); 10 gets(str1); 11 char *p = str1; 12 printf("輸入一個字符:"); 13 scanf("%c",&c); 14 printf("%s\n",strchr(str1,c));//打印字符串str1中從字符c開始的后續字符串, 15 //如果有字符串中有多個與c相同的字符,應該以第一個為准 16 int n = strchr(str1,c) - p; //??? 17 printf("%d", n); //輸出c在str1中的字符串中的位置 18 }
(2)查找任何幾個字符(標准庫中不存在)
char *strpbrk(char const *str,char const *group);
並不是查找某個特定的字符,而是查找任何一組字符第一次在字符串中出現的位置。
(3)查找一個子串(標准庫中不存在)
char *strstr(char const* s1, char const* s2)
若s2不為空,在s1中查找整個s2第一次出現的位置,否則返回NULL指針;若s2為空,則返回s1
(4)查找字符串前綴
size_t strspn(char const *str, char const *group);
size_t strcspn(char const *str, char const *group);
group字符串指定一個或多個字符。strspn從str起始位置開始,遍歷所有字符,直到第一個不符合group字符串的字符為止,返回所有符合group的字符的數目. strcspn則相反,直到第一個符合的字符為止,返回不符合的字符數目。
(5)查找標記
char *strtok(cahr *str, char const *sep);
sep是個字符串,定義了多個分隔符的字符集合,strtok找到str的下一個標記,並將其用NUL結尾,然后返回一個指向這個標記的指針。
典型用法:第一次調用時,向它傳遞一個指向字符串的指針,然后這個函數被重復調用(第一個參數為NULL),直到返回NULL,將原字符串分段輸出。
1 #include <stdio.h> 2 #include <string.h> 3 4 void print_tokens(char line[]){ 5 6 //static char whitespace[] = " \t\f\r\v\n"; 7 char *whitespace = " \t\f\r\v\n"; 8 char *token; 9 10 for (token = strtok(line, whitespace); 11 token != NULL; 12 token = strtok(NULL, whitespace)) 13 printf("Next token is %s\n", token); 14 } 15 16 int main(){ 17 18 char line[] = "int main\twosshi \f\f \r\v"; 19 20 print_tokens(line); 21 return 0; 22 }
5.內存操作(重點)
字符串都是以NUL字節結尾,所以字符串內部不能包含NUL字符,處理類似字符串時就不能夠用常規字符串處理函數,另外內存操作還可以處理數組和結構體,但該函數的返回值和參數類型均為void*
(1)void *memcpy(void *dst, void const *src, size_t length);
顯式包含需要處理的字節數,但和strn的函數不同,遇到NUL並不會停止操作,可以復制任何類型的值,第三個參數指定復制長度(以字節計算)。
若是字符數組:char a[n], b[n],則memcpy(a, b, n);表示從b數組復制n個字節到a,但如果是a和b是整型數組,則memcpy(a, b, sizeof(b));
另外如果只有部分內容需要復制,則需要復制的數量需要在第三個參數中指明,對於長度大於一個字節的數據,需要數量和數據類型的長度相乘;memcpy(a, b, count*sizeof(b));
(2)void *memmove(void *dst, void const *src, size_t length);主要用於源和目標參數存在重疊的情況
(3)void *memcmp(void const*a, void const *b, size_t length);只能比較單字節的數據,一共比較length個字節,函數的返回值只根據length來確定
(4)void *memchr(void const*a, int ch, size_t length);從a開始的位置開始查找ch出現的第一次的位置,並返回一個指向該位置的指針,一共length個字節
(5)void *memset(void const*a, int ch, size_t length);從a開始的length個字節都設置為字符值ch。
注意:memset最大的作用是將a的前length個字節置為0,a可以是指針,也可以是數組。另外,由於計算機中的字節為16進制,因此不能將memset中重置為1,否則會出錯。