【C語(yǔ)言】常見(jiàn)字符函數(shù)和字符串函數(shù)-創(chuàng)新互聯(lián)

1.1strlen
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),為客戶(hù)提供超值的營(yíng)銷(xiāo)型網(wǎng)站建設(shè)服務(wù),我們始終認(rèn)為:好的營(yíng)銷(xiāo)型網(wǎng)站就是好的業(yè)務(wù)員。我們已成功為企業(yè)單位、個(gè)人等客戶(hù)提供了網(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.1strcpy
char* 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.1strcat
char* 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.1strcmp
int 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.1strstr
char* 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.1strtok
char* 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.2strerror
char* 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.3memcmp
int 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é)果都是未定義的。


8.2memcpy的模擬實(shí)現(xiàn)
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.1memmove
void * memmove ( void * destination, const void * source, size_t num );

和memcpy的差別就是memmove函數(shù)處理的源內(nèi)存塊和目標(biāo)內(nèi)存塊是可以重疊的。
如果源空間和目標(biāo)空間出現(xiàn)重疊,就得使用memmove函數(shù)處理。

9.2memmove的模擬實(shí)現(xiàn)
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://www.muchs.cn/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)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司