C語言字符串函數(shù)介紹與模擬實現(xiàn)詳解
1. strlen(求字符串長度)

這個函數(shù)就是求一個字符串的長度。
注意它是不算'\0'的,即以'\0'為結(jié)束標(biāo)志,計算其之前的字符串長度,但不能沒有'\0'.
讓我們來一個有趣的例子:
int main()
{
if (strlen("abc") - strlen("abcdef"))
printf("hehe");
else
printf("haha");
return 0;
}
以上的代碼乍一眼看是3 - 6 = -3,應(yīng)該輸出haha
但是strlen函數(shù)返回的是無符號整型,所以-3被看作無符號整數(shù),應(yīng)該是一個大于0的數(shù)。
1.1 strlen 模擬實現(xiàn)
那么這個函數(shù)自己來寫應(yīng)該怎樣實現(xiàn)呢?
模擬實現(xiàn)需要考慮到所有情況:
所以 const 防止改變字符串與 assert 防止傳入空指針不可少。
size_t my_strlen(const char* a)
{
assert(a);
int count = 0;
while (*a)
{
count++;
a++;
}
return count;
}
2. strcpy(復(fù)制字符串)

這個函數(shù)用于把一個字符串內(nèi)容賦給另一個字符串內(nèi),如果目的字符串有內(nèi)容,直接覆蓋。
注意點(diǎn):strcpy復(fù)制字符串從arr2到arr1
被復(fù)制的字符串一定要帶'\0',因為這個是結(jié)束標(biāo)志
目標(biāo)空間也要足夠大且可變(可變:用數(shù)組寫,而非指針卡死)
int main()
{
char arr1[] = "xxxxxxxxxxxxxxx";
//char *p = "xxx";//不可變且空間小
char arr2[] = "abcd\0efg";
strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
2.1 strncpy函數(shù)

這個函數(shù)是不是很相像?由于strcpy 直接將一個字符串完全復(fù)制過去,
那么有沒有一個函數(shù)能只復(fù)制一部分呢?此函數(shù)就是充當(dāng)這個作用的。
它將 num 個字符從源字符串中取出,放入目的字符串。
int main()
{
char a[] = "abcde";
char b[] = "abc";
strncpy(a, b, 6);
printf("%s", a);
return 0;
}
如果遇到源字符串不夠的情況,會自動補(bǔ)0.

2.2 模擬實現(xiàn)strcpy
char* my_strcpy(char* a1, const char* a2)//原指針被修改,不加const
{
assert(a1 && a2);
char* ret = a1;
while (*a1++ = *a2++)
{
;
}
return ret;
}
來解釋一下這個寫法(*a1++ = *a2++ ):
先把a(bǔ)2賦給a1,然后各自++。當(dāng)a2為0時,這個表達(dá)式值為0,就退出循環(huán)。
因為值放在地址內(nèi),所以a1的地址給ret存好后,最后返回ret的地址就是返回a1的值.
3. strcat (追加字符)

傳入兩個字符串,將后一個字符串追加到前一個字符串上。
源字符串必須要有 '\0' 作為結(jié)束標(biāo)志,且目標(biāo)字符串足夠大且可變。(提前定義目標(biāo)數(shù)組大?。?/p>
如果需要自己給自己追加,那么就使用這個函數(shù)。

3.1 strncat 函數(shù)

就是將源字符串 num 個字符追加到目標(biāo)字符串上,如下圖:

3.2 模擬實現(xiàn)strcat
char* my_strcat(char* a, const char* b)
{
assert(a && b);
char* p = a;
//先找到a字符串為'\0'的位置
while (*a)
{
a++;
}
while (*a++ = *b++)
{
;
}
return p;
}
4. strcmp(比較兩個字符串內(nèi)容)

傳入兩個字符串,比較兩個字符串。
str1 > str2 返回正數(shù); = 返回0; < 返回負(fù)數(shù)
那么是怎么比較的呢?
記住是比較不相同的那個字符大小,跟長度沒有一點(diǎn)關(guān)系。

如圖就是比較 'e' 和 'q' 的字符大小,明顯 'q' 更大,所以返回 -1.
4.1 strncmp函數(shù)

和strncpy相似,就是將兩個字符串前num個字符比較,規(guī)則同 strcmp 函數(shù) 。
4.2 模擬實現(xiàn)strcmp
int my_strcmp(const char* a, const char* b)
{
assert(a && b);
while (*a == *b)
{
if (*b == '\0')
return 0;
a++;
b++;
}
/*if (*a > *b)
return 1;
if (*a < *b)
return -1;*/
return *a - *b;//這樣一步到位
}
5. strstr (返回str1出現(xiàn)在str2位置處第一次的指針)

就是返回b字符串在a中第一次出現(xiàn)的位置的指針,如下就會打印 am a student.
如果沒有找到就返回空指針。
int main()
{
char a[] = "I am a student.";
char b[] = "am";
printf("%s", strstr(a, b));
return 0;
}
5.1 模擬實現(xiàn)strstr
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* s1;
char* s2;
char* cp = str1;
if (*str2 == '\0')//如果傳入了""
return str1;
while (*cp)
{
s1 = cp;
s2 = str2;
while (*s1 == *s2 && *s1 && *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;
}
cp++;
}
return NULL;
}
6. strtok(分割字符串)

這個函數(shù)能以我們所需分割字符串,sep是分割的標(biāo)志,str是被分割的字符串。
下面來一個例子:
int main()
{
char a[] = "123@qq.com";
char b[] = "@.";
printf("%s\n", strtok(a, b));//分割了123
printf("%s\n", strtok(NULL, b));//分割了qq
printf("%s\n", strtok(NULL, b));//分割了com
return 0;
}
第一次分割完,之后這個函數(shù)會記住分割的位置,把目標(biāo)函數(shù)的分割標(biāo)志變?yōu)?\0'
所以這個函數(shù)會修改字符串,要小心使用。
下次使用只需要傳入空指針,這是這個函數(shù)的重點(diǎn)。
我們也可以使用循環(huán)來表達(dá)它的結(jié)果:
int main()
{
char *p = "666@qq.com";
const char* sep = ".@";
char arr[30];
char *str = NULL;
strcpy(arr, p);//將數(shù)據(jù)拷貝一份,處理arr數(shù)組的內(nèi)容
for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep))
{
printf("%s\n", str);
}
}
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Matlab實現(xiàn)帶豎線散點(diǎn)的核密度圖的繪制
核密度估計是用于估計隨機(jī)變量概率密度函數(shù)的一種非參數(shù)方法。核密度圖不失為一種用來觀察連續(xù)型變量分布的有效方法。本文將用Matlab實現(xiàn)帶豎線散點(diǎn)的核密度圖的繪制,感興趣的可以了解一下2022-08-08
c++中移動語義和完美轉(zhuǎn)發(fā)及易錯點(diǎn)
C++ 中的移動語義和完美轉(zhuǎn)發(fā)是 C++11 引入的兩個重要特性,它們分別用于提高性能和靈活性,這篇文章主要介紹了c++中移動語義和完美轉(zhuǎn)發(fā),需要的朋友可以參考下2023-09-09
C++實現(xiàn)學(xué)生宿舍管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)學(xué)生宿舍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
詳細(xì)解析命令行的getopt_long()函數(shù)
getopt_long支持長選項的命令行解析,函數(shù)中的參數(shù)argc和argv通常直接從main()的兩個參數(shù)傳遞而來2013-09-09
C++實現(xiàn)二分法求連續(xù)一元函數(shù)根
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)二分法求連續(xù)一元函數(shù)根,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-06-06

