不受限制的字符串函數(shù),比如說strcpy、strcmp等等,我們最常用的字符串函數(shù)都是不受限制的,只是通過尋找字符串參數(shù)結(jié)尾的NULL字節(jié)來判斷它的長度。那么什么是受限制的字符串函數(shù)呢?通過下面的例子我們來一起詳細(xì)了解一下
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供融安網(wǎng)站建設(shè)、融安做網(wǎng)站、融安網(wǎng)站設(shè)計、融安網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、融安企業(yè)網(wǎng)站模板建站服務(wù),10余年融安做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
strcpy:
原型:char*strcpy(char*strDestination,constchar*strSource );
這個函數(shù)把參數(shù)src字符串復(fù)制到dest參數(shù)中,在使用這個函數(shù)時需要注意,首先,必須保證目標(biāo)字符數(shù)組的空間足以容納需要復(fù)制的字符串,為什么呢?如果字符串比數(shù)組長,多余的字符仍然會被復(fù)制,這就導(dǎo)致它們會覆蓋原先存儲在數(shù)組后面的內(nèi)存空間的值。其次,目標(biāo)參數(shù)應(yīng)該是可被修改的,所以它必須是個字符數(shù)組或者是一個指向動態(tài)分配內(nèi)存的數(shù)組的指針。
1.strcpy模擬實現(xiàn):
char *my_strcpy(char *dest, const char *src) { char *ret = dest; assert(src != NULL); assert(dest != NULL); while (*dest++ = *src++) { ; } return ret; }
strncpy: 把src所指向的字符串中以src地址開始的前n個字節(jié)復(fù)制到dest所指的數(shù)組中,并返回dest。
上面是不受限制的字符串函數(shù),那么為什么會有strncpy這樣一類受限制的字符串函數(shù)呢?
就拿這兩個函數(shù)來說,strcpy只是復(fù)制字符串,但不限制復(fù)制的數(shù)量,很容易造成緩沖溢出。strncpy要安全一些。strncpy能夠選擇一段字符輸出,strcpy則不能。
下面是strncpy模擬實現(xiàn):
char *my_strncpy(char *dest, const char *src, int n) { char *ret = dest; assert(dest); assert(src); while (n--) { *dest++ = *src++; } *dest = '\0'; return ret; }
2.將兩個字符串連接,我們可以使用strcat函數(shù)
函數(shù)原型:
char *strcat( char *strDestination, const char *strSource );
把src所指字符串添加到dest結(jié)尾處(覆蓋dest結(jié)尾處的'\0')。
src和dest所指內(nèi)存區(qū)域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針。
char *my_strcat(char *dest, const char *src) { char *ret = dest; assert(src != NULL); assert(dest != NULL); while (*dest) { dest++; } while (*dest++ = *src++) { ; } return ret; }
strncat:
功能
把src所指字符串的前n個字符添加到dest所指字符串的結(jié)尾處,并覆蓋dest所指字符串結(jié)尾的'\0',從而實現(xiàn)字符串的連接。
說明
src和dest所指內(nèi)存區(qū)域不可以重疊,并且dest必須有足夠的空間來容納src的字符串。
返回值
返回指向dest的指針。
char *my_strncat(char *dest, const char *src, int len) { char *ret = dest; assert(dest); assert(src); while (*dest) { dest++; } while (len--) { *dest = *src; dest++; src++; } *dest = '\0'; return ret; }
3.strcmp函數(shù):比較兩個字符串。
有一個需要注意的地方是
當(dāng)s1<s2時,返回為負(fù)數(shù);
當(dāng)s1=s2時,返回值= 0;
當(dāng)s1>s2時,返回正數(shù)。
即:兩個字符串自左向右逐個字符相比(按ASCII值大小相比較),直到出現(xiàn)不同的字符或遇'\0'為止。
有的人以為返回值是1和-1,分別代表大于和小于,如果你也這樣想,那就錯了。ANSI標(biāo)準(zhǔn)規(guī)定,返回值為正數(shù),負(fù)數(shù),0 。而確切數(shù)值是依賴不同的C實現(xiàn)的。
int my_strcmp(const char *str1, const char *str2) { assert(str1); assert(str2); while (*str1 == *str2) { if (*str1 == '\0') return 0; str1++; str2++; } if (*str1 - *str2 > 0) return -1; else return 1; }
strncmp函數(shù)原型:
int strncmp ( const char * str1, const char * str2, size_t n );
參數(shù)str1, str2 為需要比較的兩個字符串,n為要比較的字符的數(shù)目。
字符串大小的比較是以ASCII 碼表上的順序來決定,此順序亦為字符的值。strncmp()首先將s1 第一個字符值減去s2 第一個字符值,若差值為0 則再繼續(xù)比較下個字符,直到字符結(jié)束標(biāo)志'\0',若差值不為0,則將差值返回。例如字符串"Ac"和"ba"比較則會返回字符"A"(65)和'b'(98)的差值(-33)。注意:要比較的字符包括字符串結(jié)束標(biāo)志'\0',而且一旦遇到'\0'就結(jié)束比較,無論n是多少,不再繼續(xù)比較后邊的字符。
strncmp函數(shù)模擬實現(xiàn):
int my_strncmp(const char *dest, const char*src, int count) { assert(dest); assert(src); while (count>0 && (*dest == *src)) { if (*dest == '\0') return 0; dest++; src++; count--; } return *dest - *src; }
4.為了在字符串中查找一個子串,我們可以使用strstr函數(shù)
函數(shù)原型:
char*strstr(constchar*string,constchar*strCharSet );
這個函數(shù)在s1中查找整個s2第一次出現(xiàn)的起始位置,并返回一個指向該位置的指針。如果s2沒有完整地出現(xiàn)在s1的任何地方,函數(shù)將返回一個NULL指針。如果第二個參數(shù)是一個空字符串,函數(shù)就返回s1。
char *my_strstr(const char *str, const char *substr) { assert(str != NULL); assert(substr != NULL); char *s1 = (char *)str; char *s2 = (char *)substr; char *start = (char *)str; while (*start) { s1 = start; while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2)) { s1++; s2++; } if (*s2 == '\0') return start; s2 = (char *)substr; start++; } return NULL; }
strrstr:
標(biāo)準(zhǔn)庫中并不存在這樣的函數(shù),當(dāng)然,如果需要,也可以很容易實現(xiàn)
strrstr函數(shù)在字符串s1中查找s2最后出現(xiàn)的位置
char* my_strrstr(char const *s1, char const *s2) { char *last = NULL; //將指針初始化為已經(jīng)找到的前一次匹配位置 char *current = NULL; assert(s1); assert(s2); if (*s2 ) //只有在第二個字符串不為空時才進(jìn)行查找 { current = (char *)strstr(s1, s2);//s2在s1中第一次出現(xiàn)的位置 while (current != NULL) { //每次找到字符串時,讓指針指向它的起始位置,然后查找該字符串下一個匹配位置 last = current; current = (char*)strstr(last + 1, s2); } } return last; }
5.在一個字符串中查找一個特定字符最容易的方法是使用strchr函數(shù)
這個函數(shù)比較簡單,下面是模擬實現(xiàn):
#include<stdio.h> #include<stdlib.h> char *my_strchr(const char*str, int ch) { while (*str) { if (*str == ch) return (char*)str; str++; } return NULL; } int main() { char *str = "happy"; char *ret = my_strchr(str, 'a'); if (ret != NULL) { printf("%c\n", *ret); } system("pause"); return 0; }
strrchr:
strrchr() 函數(shù)查找字符在指定字符串中從后面開始的第一次出現(xiàn)的位置,如果成功,則返回從該位置到字符串結(jié)尾的所有字符,如果失敗,則返回 false。與之相對應(yīng)的是strstr()函數(shù),它查找字符串中首次出現(xiàn)指定字符的位置。
函數(shù)原型:
char*strrchr(constchar*string,intc );
char *my_strrchr(char *str, char ch) { char *ptr = NULL; assert(str); while (*str) { if (*str == ch) ptr = str; str++; } if (ptr != 0) return ptr; return 0; } int main() { char ch = 0; char *ret = NULL; char *arr = "feabadc"; printf("請輸入一個你要查找的字符:"); scanf_s("%c", &ch); ret = my_strrchr(arr, ch); printf("%s\n", *ret); system("pause"); return 0; }
當(dāng)然,關(guān)于str這樣的函數(shù)還有很多,這里模擬實現(xiàn)了一些經(jīng)常用的函數(shù),希望互相借鑒幫助。
當(dāng)前標(biāo)題:關(guān)于str家族
新聞來源:http://jinyejixie.com/article36/pgiosg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、定制網(wǎng)站、動態(tài)網(wǎng)站、全網(wǎng)營銷推廣、用戶體驗、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)