大齡失業(yè)學生轉(zhuǎn)碼日記:2022-12-03(字符函數(shù)與字符串函數(shù)一)-創(chuàng)新互聯(lián)

目錄
  • 一、求字符串長度
    • 1.1strlen
    • 1.2注意:
  • 二、長度不受限制的字符串函數(shù)
    • 2.1strcpy
    • 2.2strcat
    • 2.3strcmp
  • 三、長度受限制的字符串函數(shù)
    • 3.1strncpy
    • 3.2strncat
    • 3.3strncmp

C語言中對字符和字符串有很多處理,但是C語言本身沒有字符串類型,字符串通常放在常量字符串中或者字符數(shù)組中。
字符串常量適用于那些對它不做修改的字符串函數(shù)。

創(chuàng)新互聯(lián)建站主營隰縣網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,成都APP應用開發(fā),隰縣h5小程序設計搭建,隰縣網(wǎng)站營銷推廣歡迎隰縣等地區(qū)企業(yè)咨詢一、求字符串長度 1.1strlen

求字符串長度

size_t strlen ( const char * str );
#includeint main()
{int len = strlen("abcdef");
	printf("%d\n", len);
	return 0;
}//6

結(jié)果
在這里插入圖片描述
上一篇寫strlen()函數(shù)的模擬實現(xiàn)中有3種方法:大齡失業(yè)學生轉(zhuǎn)碼日記:2022-12-02(strlen函數(shù))

1、計數(shù)器的方法;

2、遞歸的方法;

3、指針-指針的方法

#include 
#include//因為求的是字符串長度,不會改變str所指向字符串的內(nèi)容,所以加const修飾,
//即使str所指向的內(nèi)容想要被修改也沒有機會了。
int my_strlen(const char* str)
{//斷言:保證指針的有效性:
	assert(str != NULL);
	//用計數(shù)器的方法實現(xiàn):
	int count = 0;
	while (*str != '\0')//或while(*str)都可以
	{count++;
		str++;
	}
	return count;
}
int main()
{int len = my_strlen("abcdef");
	//表面?zhèn)鞯氖亲址瑢嶋H傳的是字符串首字符地址。
	printf("%d\n", len);
	return 0;
}

結(jié)果
在這里插入圖片描述
sizeof——是操作符,計算大小。sizeof計算的結(jié)果返回的類型是size_t;size_t 是專門為sizeof的返回值設計的。
size_t——其實是unsigned int類型,只表示正數(shù)。
strlen()函數(shù)返回的是無符號數(shù),兩個無符號的數(shù)相減得到的也是無符號的數(shù),比如下述代碼中會把-3當做無符號的數(shù)處理,是一個非常大的正數(shù)而會引入bug。

#include#includeint main()
{if (strlen("abc") - strlen("abcdef") >0)
	{printf(">");
	}
	else
	{printf("<=");
	}
	return 0;
}

結(jié)果
在這里插入圖片描述
strlen()的返回值可以寫成int類型,size_t類型或unsigned_int類型都可以。

上述代碼強制類型轉(zhuǎn)換為int可以得出“<=”:

#include#includeint main()
{if ((int)strlen("abc") - (int)strlen("abcdef") >0)
	{printf(">");
	}
	else
	{printf("<=");
	}
	return 0;
}

結(jié)果
在這里插入圖片描述

1.2注意:

使用庫函數(shù)時需要包含頭文件,不包含會有bug。
使用strlen()函數(shù)時:
字符串以 ‘\0’ 作為結(jié)束標志,strlen函數(shù)返回的是在字符串中 ‘\0’ 前面出現(xiàn)的字符個數(shù)(不包
含 ‘\0’ )。
參數(shù)指向的字符串必須要以 ‘\0’ 結(jié)束。
函數(shù)的返回值為size_t,是無符號的。

二、長度不受限制的字符串函數(shù) 2.1strcpy

strcpy()函數(shù)用來拷貝字符串,會把源字符串內(nèi)容拷貝到目標空間中,\0也會被拷貝過去。

char* strcpy(char * destination, const char * source );

把arr1的內(nèi)容拷貝放到arr2中

#include#includeint main()
{char arr1[] = "abcdef";
	char arr2[20] = {0 };
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

結(jié)果
在這里插入圖片描述
注意:在使用strcpy()函數(shù)時:
源字符串必須以 ‘\0’ 結(jié)束。
會將源字符串中的 ‘\0’ 拷貝到目標空間。
目標空間必須足夠大,以確保能存放源字符串,防止造成越界訪問而使程序崩潰。
目標空間必須可變。

#include#includeint main()
{char arr1[] = {'a','b','c','d','e','f' };
	char arr2[20] = "XXXXXXXX";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

程序會崩潰,拷貝內(nèi)容混亂
可以改為如下寫法

#include#includeint main()
{char arr1[] = {'a','b','c','d','e','f','\0' };
	char arr2[20] = "XXXXXXXX";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

結(jié)果
在這里插入圖片描述
strcpy()函數(shù)可以將源字符串內(nèi)容拷貝到已有數(shù)據(jù)的數(shù)組中。
注意:遇到\0的時候,打印也結(jié)束了。所以即使目標空間在\0(這里的\0是從源數(shù)據(jù)中拷貝的)后面還有數(shù)據(jù)也不能打印了。

#include#includeint main()
{char arr1[] = {'a','b','c','\0','d','e','f' };
	char arr2[20] = "XXXXXXXX";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

結(jié)果
在這里插入圖片描述
strcpy()函數(shù)的模擬實現(xiàn):

#include#include 
//把源頭數(shù)據(jù)拷貝到目標空間中,整個過程中,源數(shù)據(jù)是不需要發(fā)生變化的,目標空間需要變化
//所以在源數(shù)據(jù)前面可以用const修飾限定,保護源頭數(shù)據(jù)。
char* my_strcpy(char* dest, const char* src)
{char* ret = dest;
	assert(dest && src);
	while (*src)
	{*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;//拷貝\0
	return ret;
}
int main()
{char arr1[] = {'a','b','c','d','e','f','\0' };
	char arr2[] = "xxxxxxxx";
	my_strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}//abcdef

結(jié)果
在這里插入圖片描述

2.2strcat

把源字符串內(nèi)容追加到目標字符串的后面。

char * strcat ( char * destination, const char * source );

strcpy()函數(shù)是拷貝,覆蓋原來的數(shù)據(jù)。
strcat()函數(shù)是把源字符串內(nèi)容追加到目標字符串的后面。

#includeint main()
{char arr1[30] = "hello";
	char arr2[] = "world";
	//把arr2中的數(shù)據(jù)追加到arr1中
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述
原理:arr2找到arr1的‘\0’,把‘\0’覆蓋掉然后拷貝arr2的內(nèi)容。這里arr2是源字符串,‘\0’不會拷貝。

#include#includeint main()
{char arr1[30] = "hello";
	char arr2[] = {'w','o','r','l','d' };
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

源字符串并沒有以’\0’結(jié)束,程序崩潰
改為如下

#include#includeint main()
{char arr1[30] = {'h','e','l','l','o'};
	char arr2[] = "world";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述

2.3strcmp

用來比較兩個字符串。比較的是對應位置上的字符的大小——比較的是字符的ASCII碼值。a、b、c、d……按照順序ASCII碼值依次增大。

int strcmp ( const char * str1, const char * str2 );

標準規(guī)定:
第一個字符串大于第二個字符串,則返回大于0的數(shù)字;
第一個字符串等于第二個字符串,則返回0;
第一個字符串小于第二個字符串,則返回小于0的數(shù)字。

#include#includeint main()
{char arr1[] = "abcdef";
	char arr2[] = "bbq";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

結(jié)果
在這里插入圖片描述
比的不是長度。
“abcdef”;
“bbq”;
這兩個字符串對應的第一個字符比,a“abcdef”;
“abq”;
這兩個字符串對應的第一個字符相等,就比較第二個對應的字符,第二個字符相等就比較第三對……直到比較雙方的‘\0’。

#include#includeint main()
{char arr1[] = "bbq";
	char arr2[] = "bbq";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

在這里插入圖片描述

#include#includeint main()
{char arr1[] = "qbq";
	char arr2[] = "bbq";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

結(jié)果
在這里插入圖片描述
模擬實現(xiàn)strcmp()函數(shù):

#include#include 
int my_strcmp(const char* str1, const char* str2)//因為只訪問內(nèi)容不會修改這兩個字符串內(nèi)容所以可以加const保護
{//因為后面有對這兩個指針解引用操作,所以需要斷言是否是空指針
	assert(str1 && str2);
	while (*str1 == *str2)
	{if (*str1 == '\0')
		{	return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 >*str2)
	{return 1;
	}
	else
	{return -1;
	}
 
}
int main()
{char arr1[] = "abc";
	char arr2[] = "abcd";
	printf("%d\n", my_strcmp(arr1, arr2));
	return 0;
}

結(jié)果
在這里插入圖片描述
‘\0’的ASCII碼值是0。
注意:兩個字符串是不能相減的,兩個字符串不能用等號來判斷是否相等,更不能相減。

if ("abq" == "abc")

錯誤代碼,"abq"表達式產(chǎn)生的是它的a的地址(首字符的地址);
"abc"表達式產(chǎn)生的是它的a的地址;
這兩個地址一定不相等,所以不能用等號比。

if("abc" - "abq")

意思是這兩個地址相減比較的是地址,就不是比較的兩個字符串的內(nèi)容是否相等了;
所以兩個字符串不能相加,不能相減。

如果兩個字符串是常量字符串,那么二者的地址是相同的;
但是如果是兩個字符串數(shù)組,即使字符串內(nèi)容相同地址也不會相同,因為是兩個完全不同的空間。
總結(jié):

1 strcpy()函數(shù)在拷貝的時候,直到把源字符串中的\0拷貝完之后才停止拷貝,即拷貝到\0。
2 strcat()函數(shù)在追加的時候,也只在乎\0的問題,追加到\0。
3 strcmp()函數(shù)比較字符串的時候不相等就結(jié)束,相等就比較到\0。
4 這三個函數(shù)在拷貝的時候并沒有考慮拷貝的長度,一直到\0,所以這三個函數(shù)均是長度不受限制的字符串函數(shù),與字符串的長度沒有關系。這三者頭文件均是。

三、長度受限制的字符串函數(shù) 3.1strncpy

拷貝num個字符從源字符串到目標空間。
如果源字符串的長度小于num,則拷貝完源字符串之后,在目標的后邊追加0,直到num個。

char * strncpy ( char * destination, const char * source, size_t num );
#include#includeint main()
{char arr1[] = "xxxxxxxxxxxxx";
	char arr2[] = "hello world";
	//若把arr2中的hello這5個字符拷貝到arr1中:
	strncpy(arr1, arr2, 5);//只是把前5個hello拷貝過去
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述
如果長度不夠,會主動放上’\0’

#include#includeint main()
{char arr1[] = "xxxxxxxxxxxxx";
	char arr2[] = "he";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述
如果長度不夠,會主動放上’\0’
strncpy()函數(shù)相對較靈活,更可控、相對安全。

3.2strncat

把源字符串的num個字符追加到目標空間中。

char * strncat ( char * destination, const char * source, size_t num );
#include#includeint main()
{char arr1[20] = "hello";
	char arr2[] = "world";
	//把arr2中的world這5個字符追加到arr1中
	strncat(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[20] = "hello";
	char arr2[] = "world";
	//把arr2中的world中的3個字符追加到arr1中
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[20] = "hello\0";
	char arr2[] = "world";
	//把arr2中的world中的3個字符追加到arr1中
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[20] = "hello\0xxxxxxx";
	char arr2[] = "world";
	//把arr2中的world中的3個字符追加到arr1中
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述
strncat追加后還是字符串,所以會在追加指定的幾個字符后主動自己加上\0,所以追加完就停止打印。

#include#includeint main()
{char arr1[20] = "hello\0xxxxxxx";
	char arr2[] = "world";
	//把arr2中的world這5個字符追加到arr1中
	strncat(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[20] = "helloxxxxxxx";
	char arr2[] = "world";
	strncat(arr1, arr2, 7);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[20] = "helloxxxxxxx";
	char arr2[] = "world";
	//把arr2中的world中3個字符追加到arr1中
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

結(jié)果
在這里插入圖片描述
注意:
1、遇到\0;
2、追加的數(shù)字小于源字符串長度時,追加完要追加的字符后就不追加了。

3.3strncmp

比較num個字符串大小。

int strncmp ( const char * str1, const char * str2, size_t num );
#include#includeint main()
{char arr1[] = "abcdef";
	char arr2[] = "abcqqqqqq";
	int ret = strncmp(arr1, arr2, 3);
	printf("%d\n", ret);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[] = "abcdef";
	char arr2[] = "abcqqqqqq";
	int ret = strncmp(arr1, arr2, 4);
	printf("%d\n", ret);
	return 0;
}

結(jié)果
在這里插入圖片描述

#include#includeint main()
{char arr1[] = "abcwef";
	char arr2[] = "abcqqqqqq";
	int ret = strncmp(arr1, arr2, 4);
	printf("%d\n", ret);
	return 0;
}

結(jié)果
在這里插入圖片描述
總結(jié):
strncpy()函數(shù) —— 拷貝

strncat ()函數(shù) —— 追加

strncmp()函數(shù) —— 比較

這三者是長度受限制的字符串函數(shù),頭文件均是。

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁標題:大齡失業(yè)學生轉(zhuǎn)碼日記:2022-12-03(字符函數(shù)與字符串函數(shù)一)-創(chuàng)新互聯(lián)
本文網(wǎng)址:http://bm7419.com/article20/hohjo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供域名注冊、企業(yè)建站ChatGPT、虛擬主機、微信小程序、網(wǎng)站導航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設