strcat的介紹及實(shí)現(xiàn)
strcat
的作用就是字符串追加,即將一個(gè)字符串添加到另一個(gè)字符串末尾。
那既然要追加字符串,要怎么找到目標(biāo)字符串的末尾呢?所以這就要求目標(biāo)空間中要有'\0'
,找到'\0'
就是找到末尾了。需要注意的是此函數(shù)內(nèi)部在找末尾時(shí),找的是目標(biāo)空間中第一個(gè)'\0'
的位置,然后從此位置開始追加。又開始就要有結(jié)束,所以源字符串中也要有'\0'
。既然要追加字符串,所以目標(biāo)空間必須可以被修改。strcat
將源字符串追加到目標(biāo)字符串末尾,那么目標(biāo)空間就必須足夠大。還有一點(diǎn)需要注意的是,此函數(shù)返回的是目標(biāo)空間首元素地址。
根據(jù)上面總結(jié)了以下幾點(diǎn):
- 目標(biāo)空間要有
'\0'
,(開始追加的地方) - 源頭字符串中要有
'\0'
,(追加到此處結(jié)束) - 目標(biāo)空間要足夠大且可修改
實(shí)現(xiàn)方法如下:
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;//記錄目標(biāo)字符串首元素地址
assert(dest && src);
//1.找到目標(biāo)空間的'\0'
while (*dest != '\0')
{
dest++;
}
//2.拷貝數(shù)據(jù)
while (*dest++ = *src++)
{
;
}
//3.返回參數(shù)
return ret;
}
int main()
{
char arr1[20] = "hello";
char* p = "world";
printf("%s\n",my_strcat(arr1, p));
return 0;
}
再來思考這么一個(gè)問題:如果用strcat
自己給自己追加會發(fā)生什么,如下:
my_strlen(arr1,arr1);
仔細(xì)分析一下會發(fā)現(xiàn),當(dāng)找到目標(biāo)空間的'\0'
時(shí),源字符串就會將此'\0'
修改,那么在繼續(xù)追加字符時(shí),由于源字符串和目標(biāo)空間相同,且'\0'
被修改,則此函數(shù)就無法結(jié)束,從而導(dǎo)致程序崩潰。
strcmp的介紹及實(shí)現(xiàn)
strcmp
是比較兩個(gè)字符串的大小關(guān)系的函數(shù)。
關(guān)于比較規(guī)則:比較的是兩個(gè)字符串中對應(yīng)位置上的字符,一開始比較的則是兩個(gè)字符串的首元素所對應(yīng)的字典序。如果兩個(gè)所對應(yīng)的字典序不同,則會繼續(xù)比較,直到比較到兩個(gè)不同的字符或是找到了'\0'
。如果比較的結(jié)果是:
-
str1 > str2
,則返回大于0的數(shù); -
str1 = str2
,則會返回0,這里的相等是直至字符串末尾都相等; -
str1 < str2
,則會返回小于0的數(shù)
關(guān)于函數(shù)參數(shù):strcmp
返回值是一個(gè)整形,接收的參數(shù)是兩個(gè)字符串的地址,而此地址指向的地址是不可修改的,所以用const
修飾。
模擬實(shí)現(xiàn)如下:
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
//判斷字符串是否結(jié)束
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
//比較對應(yīng)值
if (*str1 > *str2)
return 1;
else
return -1;
//此處也可以直接用兩值的差作為返回值
//即:return *str1 - *str2;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
小結(jié)
通過上面介紹的strcat
,strcmp
這兩個(gè)函數(shù),及在 字符串函數(shù)的模擬實(shí)現(xiàn)中介紹的strcmp
函數(shù),我們發(fā)現(xiàn)這些都是長度不受限制的字符串函數(shù)。因?yàn)檫@個(gè)特點(diǎn),所以我們在使用時(shí)存在一些安全性的問題,這就要求我們在使用時(shí)要格外的小心,防止發(fā)生包括但不限于越界訪問,死循環(huán)導(dǎo)致的程序崩潰等問題。
所以c語言也引入了如strncpy
,strncat
,strncmp
等長度受限制的字符串函數(shù),下面我會對這些函數(shù)一一介紹。
strncpy的介紹及實(shí)現(xiàn)
strncpy
就是拷貝num
個(gè)字符從源字符串到目標(biāo)空間。
在使用時(shí)當(dāng)然還有一些細(xì)節(jié)要注意:
- 當(dāng)要拷貝的字符個(gè)數(shù)
num
大于源頭字符串的的長度時(shí),會在目標(biāo)空間繼續(xù)拷貝'\0'
直至達(dá)到num
個(gè); - 如果
num
小于源字符串的話,strncpy
并不會在目標(biāo)空間多拷貝一個(gè)'\0'
表示結(jié)束; - 相較于
strcpy
,strncpy
多了一個(gè)參數(shù)類型為size_t
的參數(shù),這就是需要拷貝的字符的個(gè)數(shù)。
strncpy
模擬實(shí)現(xiàn)圖解:文章來源:http://www.zghlxwxcb.cn/news/detail-729429.html
模擬實(shí)現(xiàn):文章來源地址http://www.zghlxwxcb.cn/news/detail-729429.html
#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dest, const char* src, size_t num)
{
char* ret = dest;
assert(dest && src);
//拷貝源字符串中的字符到目標(biāo)空間,記錄剩下需要拷貝的字符,直到num為0或源字符串結(jié)束
while (num && (*dest++ = *src++))
num--;
//判斷拷貝是否結(jié)束,如果沒有繼續(xù)拷貝num個(gè)'\0'
if (num)
while (--num)
*dest++ = '\0';
return ret;
}
int main()
{
char arr1[20] = "hello world";
char arr2[] = "love";
printf("%s\n", my_strncpy(arr1, arr2, 4));
return 0;
}
到了這里,關(guān)于【c語言】字符串函數(shù)的模擬實(shí)現(xiàn)(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!