溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

關(guān)于str家族

發(fā)布時間:2020-04-10 16:07:53 來源:網(wǎng)絡(luò) 閱讀:283 作者:迎著風(fēng)奔跑 欄目:編程語言

不受限制的字符串函數(shù),比如說strcpy、strcmp等等,我們最常用的字符串函數(shù)都是不受限制的,只是通過尋找字符串參數(shù)結(jié)尾的NULL字節(jié)來判斷它的長度。那么什么是受限制的字符串函數(shù)呢?通過下面的例子我們來一起詳細(xì)了解一下

strcpy:

原型:char *strcpy( char *strDestination, const char *strSource );

這個函數(shù)把參數(shù)src字符串復(fù)制到dest參數(shù)中,在使用這個函數(shù)時需要注意,首先,必須保證目標(biāo)字符數(shù)組的空間足以容納需要復(fù)制的字符串,為什么呢?如果字符串比數(shù)組長,多余的字符仍然會被復(fù)制,這就導(dǎo)致它們會覆蓋原先存儲在數(shù)組后面的內(nèi)存空間的值。其次,目標(biāo)參數(shù)應(yīng)該是可被修改的,所以它必須是個字符數(shù)組或者是一個指向動態(tài)分配內(nèi)存的數(shù)組的指針。

1.strcpy模擬實(shí)現(xiàn):

char *my_strcpy(char *dest, const char *src)
{
	char *ret = dest;
	assert(src != NULL);
	assert(dest != NULL);
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

  strncpy:  把src所指向的字符串中以src地址開始的前n個字節(jié)復(fù)制到dest所指的數(shù)組中,并返回dest。 

  上面是不受限制的字符串函數(shù),那么為什么會有strncpy這樣一類受限制的字符串函數(shù)呢?

就拿這兩個函數(shù)來說,strcpy只是復(fù)制字符串,但不限制復(fù)制的數(shù)量,很容易造成緩沖溢出。strncpy要安全一些。strncpy能夠選擇一段字符輸出,strcpy則不能。

下面是strncpy模擬實(shí)現(xiàn):

char *my_strncpy(char *dest, const char *src, int n)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (n--)
	{
		*dest++ = *src++;
	}
		*dest = '\0';
	return ret;
}


2.將兩個字符串連接,我們可以使用strcat函數(shù)

函數(shù)原型:

char *strcat( char *strDestination, const char *strSource );

功能:

把src所指字符串添加到dest結(jié)尾處(覆蓋dest結(jié)尾處的'\0')。

說明:

src和dest所指內(nèi)存區(qū)域不可以重疊且dest必須有足夠的空間來容納src的字符串。

返回指向dest的指針。

char *my_strcat(char *dest, const char *src)
{
	char *ret = dest;
	assert(src != NULL);
	assert(dest != NULL);
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
		{
			;
		}
	return ret;
}


strncat:

功能

把src所指字符串的前n個字符添加到dest所指字符串的結(jié)尾處,并覆蓋dest所指字符串結(jié)尾的'\0',從而實(shí)現(xiàn)字符串的連接。

說明

src和dest所指內(nèi)存區(qū)域不可以重疊,并且dest必須有足夠的空間來容納src的字符串。

返回值

返回指向dest的指針。

char *my_strncat(char *dest, const char *src, int len)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (*dest)
	{
		dest++;
	}
	while (len--)
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return ret;
}


3.strcmp函數(shù):比較兩個字符串。

有一個需要注意的地方是

當(dāng)s1<s2時,返回為負(fù)數(shù);

當(dāng)s1=s2時,返回值= 0;

當(dāng)s1>s2時,返回正數(shù)。

即:兩個字符串自左向右逐個字符相比(按ASCII值大小相比較),直到出現(xiàn)不同的字符或遇'\0'為止。

有的人以為返回值是1和-1,分別代表大于和小于,如果你也這樣想,那就錯了。ANSI標(biāo)準(zhǔn)規(guī)定,返回值為正數(shù),負(fù)數(shù),0 。而確切數(shù)值是依賴不同的C實(shí)現(xiàn)的。

int my_strcmp(const char *str1, const char *str2)
{
	assert(str1);
	assert(str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
		if (*str1 - *str2 > 0)
			return -1;
		else
			return 1;
}


strncmp函數(shù)原型:

int strncmp ( const char * str1, const char * str2, size_t n );

  參數(shù)str1, str2 為需要比較的兩個字符串,n為要比較的字符的數(shù)目。

  字符串大小的比較是以ASCII 碼表上的順序來決定,此順序亦為字符的值。strncmp()首先將s1 第一個字符值減去s2 第一個字符值,若差值為0 則再繼續(xù)比較下個字符,直到字符結(jié)束標(biāo)志'\0',若差值不為0,則將差值返回。例如字符串"Ac"和"ba"比較則會返回字符"A"(65)和'b'(98)的差值(-33)。注意:要比較的字符包括字符串結(jié)束標(biāo)志'\0',而且一旦遇到'\0'就結(jié)束比較,無論n是多少,不再繼續(xù)比較后邊的字符。


strncmp函數(shù)模擬實(shí)現(xiàn):

int my_strncmp(const char *dest, const char*src, int count)
{
	assert(dest);
	assert(src);
	while (count>0 && (*dest == *src))
	{
		if (*dest == '\0')
			return 0;
		dest++;
		src++;
		count--;
	}
	return *dest - *src;
}


4.為了在字符串中查找一個子串,我們可以使用strstr函數(shù)

函數(shù)原型:

char *strstr( const char *string, const char *strCharSet );

這個函數(shù)在s1中查找整個s2第一次出現(xiàn)的起始位置,并返回一個指向該位置的指針。如果s2沒有完整地出現(xiàn)在s1的任何地方,函數(shù)將返回一個NULL指針。如果第二個參數(shù)是一個空字符串,函數(shù)就返回s1。


char *my_strstr(const char *str, const char *substr)
{
	assert(str != NULL);
	assert(substr != NULL);
	char *s1 = (char *)str;
	char *s2 = (char *)substr;
	char *start = (char *)str;
	while (*start)
	{
		s1 = start;
		while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return start;
		s2 = (char *)substr;
		start++;
	}
	return NULL;
}


strrstr:

標(biāo)準(zhǔn)庫中并不存在這樣的函數(shù),當(dāng)然,如果需要,也可以很容易實(shí)現(xiàn)

strrstr函數(shù)在字符串s1中查找s2最后出現(xiàn)的位置

char* my_strrstr(char const *s1, char const *s2)
{
	char *last = NULL;  //將指針初始化為已經(jīng)找到的前一次匹配位置
	char *current = NULL;
	assert(s1);
	assert(s2);
	if (*s2 )  //只有在第二個字符串不為空時才進(jìn)行查找
	{
		current = (char *)strstr(s1, s2);//s2在s1中第一次出現(xiàn)的位置
		while (current != NULL)
		{
	//每次找到字符串時,讓指針指向它的起始位置,然后查找該字符串下一個匹配位置	
			last = current;   
			current = (char*)strstr(last + 1, s2);
		}
	}
	return last;
}


5.在一個字符串中查找一個特定字符最容易的方法是使用strchr函數(shù)

這個函數(shù)比較簡單,下面是模擬實(shí)現(xiàn):

#include<stdio.h>
#include<stdlib.h>

char *my_strchr(const char*str, int ch)
{
	while (*str)
	{
		if (*str == ch)
			return (char*)str;
		str++;
	}
	return NULL;
}
int main()
{
	char *str = "happy";
	char *ret = my_strchr(str, 'a');
	if (ret != NULL)
	{
		printf("%c\n", *ret);
	}
	system("pause");
	return 0;
}


strrchr:

strrchr() 函數(shù)查找字符在指定字符串中從后面開始的第一次出現(xiàn)的位置,如果成功,則返回從該位置到字符串結(jié)尾的所有字符,如果失敗,則返回 false。與之相對應(yīng)的是strstr()函數(shù),它查找字符串中首次出現(xiàn)指定字符的位置。

函數(shù)原型:

char *strrchr( const char *string, int c );

char *my_strrchr(char *str, char ch)
{
	char *ptr = NULL;
	assert(str);
	while (*str)
	{
		if (*str == ch)
			ptr = str;
		str++;
	}
	if (ptr != 0)
		return ptr;
	return 0;
}
int main()
{
	char ch = 0;
	char *ret = NULL;
	char *arr = "feabadc";
	printf("請輸入一個你要查找的字符:");
	scanf_s("%c", &ch);
	ret = my_strrchr(arr, ch);
	printf("%s\n", *ret);
	system("pause");
	return 0;
}


當(dāng)然,關(guān)于str這樣的函數(shù)還有很多,這里模擬實(shí)現(xiàn)了一些經(jīng)常用的函數(shù),希望互相借鑒幫助。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI