size_t strlen(const char* str);字符串已經(jīng)'\0'作為結(jié)束標志,strlen函數(shù)返回的是在字符串中'\0'前面出現(xiàn)的字符個數(shù)(不包含'\0')。

參數(shù)指向的字符串必須以'\0'結(jié)束。
注意函數(shù)的返回值為size_t,是無符號整形(易錯點)。
下面看一段代碼:
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;
}我們知道無符號整形的運算操作的是補碼,代碼中的3-6可以看做是3+(-6),補碼相加的結(jié)果是11111111111111111111111111111101對于一個有符號的數(shù)字,最高位是1為負數(shù),但是返回值是無符號的數(shù),當這個補碼被當做一個無符號的數(shù)字處理的時候是一個非常大的正數(shù),所以程序運行結(jié)果為str2>str1。
1.2strlen的模擬實現(xiàn)strlen的模擬實現(xiàn)有三種方法:計數(shù)器、遞歸、指針。
方法一(計數(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;//沒有修改,只移查找
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é)束。
會將源字符串中的'\0'拷貝到目標空間。
目標空間必須足夠大,以確定能存放源字符串。
目標空間必須可變。
2.2strcpy的模擬實現(xiàn)char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* start = dest;//記錄進入的原始的dest
while (*dest++ = *src++)//后置++
{
;
}
return start;
}3.1strcatchar* strcat(char* dest, const char* src);源字符串必須以'\0'結(jié)束。
目標空間必須足夠大,能容納下源字符串的內(nèi)容。
目標空間可修改。
3.2strcat的模擬實現(xiàn)strcat的模擬實現(xiàn)和strcpy的模擬實現(xiàn)有著異曲同工之妙,只是在strcpy模擬實現(xiàn)的基礎(chǔ)上加了一個找目標字符串中的'\0'。
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* start = dest;
//找目標字符串中的'\0'
while ('\0' != *dest)
{
dest++;
}
//追加
while (*dest++ = *src++)
{
;
}
return start;
}4.1strcmpint strcmp(const char* str1, const char* str2);標準規(guī)定:
第一個字符串大于第二個字符串,則返回大于0的數(shù)字。
第一個字符串等于第二個字符串,則返回0。
第一個字符串小于第二個字符串,則返回小于0的數(shù)字。
4.2strcmp的模擬實現(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.長度受限制的字符串函數(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 );這是三個函數(shù)和長度受限制的字符串函數(shù)是相似的,只不過使用傳參時多一個參數(shù)num,需要指明操作字符串的字節(jié)數(shù)目,在模擬實現(xiàn)的時候,只要多傳遞一個參數(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的模擬實現(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;//記錄移動的位置
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ù)是個字符串,定義了用作分隔符的字符集和。
第一個參數(shù)指定一個字符串,它包含了0個或者多個由sep字符串中一個或多個分隔符分割的標記。
strtok函數(shù)找到str中的下一個標記,并將其用\0結(jié)尾,返回一個指向這個標記的指針。(注:strtok函數(shù)會改變被操作的字符串,所以在使用strtok函數(shù)切分的字符串一般都是臨時拷貝的內(nèi)容并且可以修改。)
strtok函數(shù)的第一個參數(shù)不為NULL,函數(shù)將找到str中第一個標記,strtok函數(shù)將保存它在字符串中的位置。
strtok函數(shù)的第一個參數(shù)為NULL,函數(shù)將在同一個字符串中被保存的位置開始,查找下一個標記。
如果字符串中不存在更多的標記,則返回NULL指針。
下面看一個程序:
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;
}這種代碼看起來并不是很好,所以可以對以上代碼進行改進:
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);返回錯誤碼所對應的錯誤信息。
#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);比價從ptr1和ptr2指針開始的num個字節(jié)
返回值如下:

void * memcpy ( void * destination, const void * source, size_t num );函數(shù)memcpy從source的位置開始向后復制num個字節(jié)的數(shù)據(jù)到destination的內(nèi)存位置。
這個函數(shù)在遇到 '\0' 的時候并不會停下來。
如果source和destination有任何的重疊,復制的結(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)存塊和目標內(nèi)存塊是可以重疊的。
如果源空間和目標空間出現(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海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁題目:【C語言】常見字符函數(shù)和字符串函數(shù)-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://www.chinadenli.net/article48/djhhhp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、建站公司、網(wǎng)站設(shè)計、定制開發(fā)、移動網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化
聲明:本網(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)
猜你還喜歡下面的內(nèi)容