size_t strlen(const char* str);
字符串已經(jīng)'\0'作為結(jié)束標(biāo)志,strlen函數(shù)返回的是在字符串中'\0'前面出現(xiàn)的字符個(gè)數(shù)(不包含'\0')。
創(chuàng)新互聯(lián)公司憑借在網(wǎng)站建設(shè)、網(wǎng)站推廣領(lǐng)域領(lǐng)先的技術(shù)能力和多年的行業(yè)經(jīng)驗(yàn),為客戶提供超值的營(yíng)銷型網(wǎng)站建設(shè)服務(wù),我們始終認(rèn)為:好的營(yíng)銷型網(wǎng)站就是好的業(yè)務(wù)員。我們已成功為企業(yè)單位、個(gè)人等客戶提供了網(wǎng)站制作、成都網(wǎng)站制作服務(wù),以良好的商業(yè)信譽(yù),完善的服務(wù)及深厚的技術(shù)力量處于同行領(lǐng)先地位。參數(shù)指向的字符串必須以'\0'結(jié)束。
注意函數(shù)的返回值為size_t,是無(wú)符號(hào)整形(易錯(cuò)點(diǎn))。
下面看一段代碼:
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) >0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
我們知道無(wú)符號(hào)整形的運(yùn)算操作的是補(bǔ)碼,代碼中的3-6可以看做是3+(-6),補(bǔ)碼相加的結(jié)果是11111111111111111111111111111101對(duì)于一個(gè)有符號(hào)的數(shù)字,最高位是1為負(fù)數(shù),但是返回值是無(wú)符號(hào)的數(shù),當(dāng)這個(gè)補(bǔ)碼被當(dāng)做一個(gè)無(wú)符號(hào)的數(shù)字處理的時(shí)候是一個(gè)非常大的正數(shù),所以程序運(yùn)行結(jié)果為str2>str1。
1.2strlen的模擬實(shí)現(xiàn)strlen的模擬實(shí)現(xiàn)有三種方法:計(jì)數(shù)器、遞歸、指針。
方法一(計(jì)數(shù)器)size_t my_strlen1(const char* str)
{
assert(str);
unsigned int count = 0;
while (*str != '\0')
{
str++;
count++;
}
return count;
}
方法二(遞歸)size_t my_strlen2(const char* str)
{
assert(str);
if ('\0' == *str)
return 0;
else
return 1 + my_strlen2(str+1);
}
方法三(指針)size_t my_strlen3(const char* str)
{
assert(str);
const char* dest = str;//沒(méi)有修改,只移查找
while ('\0' != *dest)
{
dest++;
}
return dest - str;
}
2.1strcpychar* strcpy(char* dest, const char* src);
Copies the C string pointed by source into
the array pointed by destination,including
the terminating null character.
源字符串必須以'\0'結(jié)束。
會(huì)將源字符串中的'\0'拷貝到目標(biāo)空間。
目標(biāo)空間必須足夠大,以確定能存放源字符串。
目標(biāo)空間必須可變。
2.2strcpy的模擬實(shí)現(xiàn)char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* start = dest;//記錄進(jìn)入的原始的dest
while (*dest++ = *src++)//后置++
{
;
}
return start;
}
3.1strcatchar* strcat(char* dest, const char* src);
源字符串必須以'\0'結(jié)束。
目標(biāo)空間必須足夠大,能容納下源字符串的內(nèi)容。
目標(biāo)空間可修改。
3.2strcat的模擬實(shí)現(xiàn)strcat的模擬實(shí)現(xiàn)和strcpy的模擬實(shí)現(xiàn)有著異曲同工之妙,只是在strcpy模擬實(shí)現(xiàn)的基礎(chǔ)上加了一個(gè)找目標(biāo)字符串中的'\0'。
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* start = dest;
//找目標(biāo)字符串中的'\0'
while ('\0' != *dest)
{
dest++;
}
//追加
while (*dest++ = *src++)
{
;
}
return start;
}
4.1strcmpint strcmp(const char* str1, const char* str2);
標(biāo)準(zhǔn)規(guī)定:
第一個(gè)字符串大于第二個(gè)字符串,則返回大于0的數(shù)字。
第一個(gè)字符串等于第二個(gè)字符串,則返回0。
第一個(gè)字符串小于第二個(gè)字符串,則返回小于0的數(shù)字。
4.2strcmp的模擬實(shí)現(xiàn)int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')//比較的字符串相等
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
5.長(zhǎng)度受限制的字符串函數(shù)strncpy、strncat、strncmp
char * strncpy ( char * destination, const char * source, size_t num );
char * strncat ( char * destination, const char * source, size_t num );
int strncmp ( const char * str1, const char * str2, size_t num );
這是三個(gè)函數(shù)和長(zhǎng)度受限制的字符串函數(shù)是相似的,只不過(guò)使用傳參時(shí)多一個(gè)參數(shù)num,需要指明操作字符串的字節(jié)數(shù)目,在模擬實(shí)現(xiàn)的時(shí)候,只要多傳遞一個(gè)參數(shù),然后限制參數(shù)的大小即可實(shí)現(xiàn)。
6.1strstrchar* strstr(const char* str1, const char* str2);
Returns a pointer to the first occurrence of str2 in str1,or a null pointer if str2 is not part of str1.
使用舉例:
int main()
{
char str[] = "This is a simple string";
char* pch;
pch = strstr(str, "simple");
strncpy(pch, "sample", 6);
puts(str);
return 0;
}
6.2strstr的模擬實(shí)現(xiàn)char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
const char* s1 = str1;//記錄str1的位置
const char* s2 = str2;//記錄str2的位置
const char* cur = str1;//記錄移動(dòng)的位置
while (*cur)
{
s1 = cur;
s2 = str2;
while (*s1 && *s2 && (*s1 == *s2))//判斷條件
{
s1++;
s2++;
}
if ('\0' == *s2)
return (char*)cur;
cur++;
}
return NULL;
}
7.1strtokchar* strtok(char* str, const char* sep);
sep參數(shù)是個(gè)字符串,定義了用作分隔符的字符集和。
第一個(gè)參數(shù)指定一個(gè)字符串,它包含了0個(gè)或者多個(gè)由sep字符串中一個(gè)或多個(gè)分隔符分割的標(biāo)記。
strtok函數(shù)找到str中的下一個(gè)標(biāo)記,并將其用\0結(jié)尾,返回一個(gè)指向這個(gè)標(biāo)記的指針。(注:strtok函數(shù)會(huì)改變被操作的字符串,所以在使用strtok函數(shù)切分的字符串一般都是臨時(shí)拷貝的內(nèi)容并且可以修改。)
strtok函數(shù)的第一個(gè)參數(shù)不為NULL,函數(shù)將找到str中第一個(gè)標(biāo)記,strtok函數(shù)將保存它在字符串中的位置。
strtok函數(shù)的第一個(gè)參數(shù)為NULL,函數(shù)將在同一個(gè)字符串中被保存的位置開(kāi)始,查找下一個(gè)標(biāo)記。
如果字符串中不存在更多的標(biāo)記,則返回NULL指針。
下面看一個(gè)程序:
int main()
{
char str[] = "- This, a sample string.";
char* pch;
printf("Splitting string \"%s\" into tokens:\n", str);
pch = strtok(str, " ,.-");
while (pch != NULL)
{
printf("%s\n", pch);
pch = strtok(NULL, " ,.-");
}
return 0;
}
這種代碼看起來(lái)并不是很好,所以可以對(duì)以上代碼進(jìn)行改進(jìn):
int main()
{
char* p = "zhangpengwei@bitedu.tech";
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);
}
}
7.2strerrorchar* strerror(int errnum);
返回錯(cuò)誤碼所對(duì)應(yīng)的錯(cuò)誤信息。
#include#include#include//必須包含的頭文件
int main()
{
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("Error opening file unexist.ent: %s\n", strerror(errno));
//errno: Last error number
return 0;
}
7.3memcmpint memcmp(const void* ptr1,
const void* ptr2,
size_t num);
比價(jià)從ptr1和ptr2指針開(kāi)始的num個(gè)字節(jié)
返回值如下:
8.1memcpy?void * memcpy ( void * destination, const void * source, size_t num );
函數(shù)memcpy從source的位置開(kāi)始向后復(fù)制num個(gè)字節(jié)的數(shù)據(jù)到destination的內(nèi)存位置。
這個(gè)函數(shù)在遇到 '\0' 的時(shí)候并不會(huì)停下來(lái)。
如果source和destination有任何的重疊,復(fù)制的結(jié)果都是未定義的。
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
9.1memmovevoid * memmove ( void * destination, const void * source, size_t num );
和memcpy的差別就是memmove函數(shù)處理的源內(nèi)存塊和目標(biāo)內(nèi)存塊是可以重疊的。
如果源空間和目標(biāo)空間出現(xiàn)重疊,就得使用memmove函數(shù)處理。
void* my_memmove(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
if (dest< src)
{
//從前往后
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//從后往前
while (count--)
{
*((char*)dest+count) = *((char*)src+count);
}
}
return ret;
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁(yè)題目:【C語(yǔ)言】常見(jiàn)字符函數(shù)和字符串函數(shù)-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://m.newbst.com/article48/djhhhp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、建站公司、網(wǎng)站設(shè)計(jì)、定制開(kāi)發(fā)、移動(dòng)網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容