C語言處理字符串及內存操作


字符串處理函數

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,否則會出錯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM