您好,登錄后才能下訂單哦!
不要懷疑,博主這次真的是在挖墳,今天整理筆記的時(shí)候才看見,所以呢,就上來備份一下,這篇呢主要是說一些關(guān)于字符串函數(shù)的知識(shí)點(diǎn),希望大家以后在使用的時(shí)候注意一下!
一、字符串基本知識(shí)
1.字符串:顧名思義,字符串即一串字符的組合,并且以NUL結(jié)尾,所以我們不能讓'\0'出現(xiàn)在字符串還 沒有結(jié)束的地方。
2.NUL:它本身并不是字符串的一部分而是一個(gè)我們用來判斷一個(gè)字符串結(jié)束與否的標(biāo)識(shí)!
3.字符串的分類:常量字符串,字符串?dāng)?shù)組。
常量字符串
一般來說我們使用常量字符串來保存那些不需要被修改的字符串
字符串?dāng)?shù)組
存放在數(shù)組里的字符串我們可以對(duì)其進(jìn)行增刪和替換
注意:若我們要使用字符串函數(shù)必須引頭文件string.h
二、串操作函數(shù)
1、字符串的長(zhǎng)度度量標(biāo)尺:strlen
函數(shù)原型:size_t strlen(char const *string)
size_t是一個(gè)無符號(hào)整數(shù)類型 所以我們不可以用兩個(gè)strlen 的結(jié)果減法運(yùn)算來判斷哪個(gè)字符串長(zhǎng)。
典型錯(cuò)誤:if((strlen(str1)-strlen(str2)) >= 0) 該表達(dá)式的結(jié)果將永遠(yuǎn)為真
**表達(dá)里面如果同時(shí)包含有符號(hào)和無符號(hào)數(shù)結(jié)果會(huì)變得不一樣
使用減法必須強(qiáng)類型轉(zhuǎn)換
int main ( ) { char *arr = "ABCD"; int ret1 = strlen( arr ); int ret2 = strlen( arr ) - 10 ; printf( "%d %d\n" , ret1, ret2 ); system( "pause" ); return 0 ; }
結(jié)果: 4 -6
2.容易失控的不受長(zhǎng)度限制串操作函數(shù)
字符串拷貝函數(shù)strcpy
由于字符串拷貝函數(shù)不能檢測(cè)字符串的長(zhǎng)度,你給它多少個(gè)字符它就拷貝多少個(gè)字符,但在程序執(zhí)行時(shí),多出來的字符會(huì)按順序存放在內(nèi)存空間中,這樣是十分不安全的,你有可能覆蓋掉了內(nèi)存中其他重要的信息。
當(dāng)原串和目標(biāo)串出現(xiàn)內(nèi)存重疊的時(shí)候我們應(yīng)該考慮原串里面的內(nèi)容會(huì)被覆蓋并丟失,此時(shí)我們應(yīng)該選擇內(nèi)存拷貝函數(shù)memmove來解決這個(gè)難題
如果新的字符串短于原字符串那么原字符串里結(jié)尾的幾個(gè)字符也無法顯示,因?yàn)樵诳截悤r(shí)它將字符串里的‘\0’也一起拷貝過來,導(dǎo)致原串中最后幾個(gè)字符落在NUL的后面!
字符連接函數(shù)strcat
strcat函數(shù)同樣不受到長(zhǎng)度的限制,我們?cè)趯⒁粋€(gè)字符連接到另一個(gè)字符串后面的時(shí)候選擇strcat函數(shù),在我們使用時(shí)同樣要給目標(biāo)字符串預(yù)留出足夠的空間來容納我們的源串,并且保證它們不會(huì)發(fā)生內(nèi)存的重疊。
如果你需要連接的字符串的長(zhǎng)度加上目標(biāo)字符串的長(zhǎng)度超過了目標(biāo)串的總長(zhǎng)則會(huì)發(fā)生段錯(cuò)誤!
不能自己連接自己!
字符串的比較函數(shù)strcmp
字符串的比較函數(shù)strcmp的原理是將字符串里的每一個(gè)對(duì)應(yīng)字符進(jìn)行比較,直到找到第一個(gè)不相等的字符比較他們的ASCII碼值后給出結(jié)論!
被比較的兩個(gè)字符串可以長(zhǎng)度不同,如果前面的字符都相同,那么短的那個(gè)字符串更?。?br /> 有一個(gè)常見的問題,許多的初學(xué)者總是將判斷條件寫成if(strcmp(str1,str2))這種寫法是絕對(duì)要避免的,因?yàn)樵摵瘮?shù)的返回值為0時(shí),結(jié)果為真(str1=str2),正好和我們平時(shí)的邏輯相反!
以上敘述的三個(gè)函數(shù)都是不受字符串的長(zhǎng)度限制,在使用時(shí)一定要注意不要忽略可用的字符串的長(zhǎng)度(避免字符串?dāng)?shù)組的越界訪問造成的內(nèi)存覆蓋丟失等)
3.長(zhǎng)受限的串操作函數(shù)
strncp(char *dest,const char *src,int n)
該函數(shù)在復(fù)制時(shí)根據(jù)傳參時(shí)規(guī)定的長(zhǎng)度復(fù)制字符串,如果src的長(zhǎng)度小于n那么數(shù)組將在未填充部分自動(dòng)填充NUL來補(bǔ)全,但如果src的長(zhǎng)度大于n那么src只會(huì)有n個(gè)字符被復(fù)制,并且該字符串不會(huì)以NUL結(jié)尾
strncat(char *dest,const char *src,int n)
該函數(shù)在連接時(shí),如果連接之后字符串總長(zhǎng)大于dest能容納的最大長(zhǎng)度src函數(shù)不會(huì)停止而是將后面的連接上去,并且在連接完最后個(gè)字符之后添加上NUL
strncmp
以上三個(gè)函數(shù)的功能和我們剛剛介紹過的strcpy,strcat,strcmp的功能主要的差別就是在長(zhǎng)度的控制上
3.字符串查找函數(shù)
查找一個(gè)字符
我們常常使用strchr和strrchr來查找字符串里某個(gè)字符的位置
strchr找到該字符第一次出現(xiàn)在該串中的位置,并返回指向它的指針。
strrchr找到該字符最后一次出現(xiàn)在該串中的位置,并返回指向它的指針。
查找任意幾個(gè)字符
strpbrk(char const *str,char const *group);
值得注意的是:如果輸入了一個(gè)任意幾個(gè)字符其中第一個(gè)字符存在于字符串里,但是后面的不存在它仍然會(huì)給你返回指向第一個(gè)字符的位置的指針~
返回原串中第一次出現(xiàn)的目標(biāo)串的任意字符的地址
匹配任何一個(gè)字符
int main ( ) { char *arr = "ABCD"; char *ret = strpbrk( arr,"BF" ); printf( "%c\n" , *ret ); system( "pause" ); return 0 ; }
查找子串strstr(const char *str,const char *str2)
庫(kù)函數(shù)里并沒有像strrstr這樣的函數(shù),但我們可以自己實(shí)現(xiàn)它!該函數(shù)也是用于在字符串里查找子串不和上面函數(shù)不一樣的是如果子串沒有完整的出現(xiàn)在原串里它將返回NULL
拓展:實(shí)現(xiàn)strrstr 出現(xiàn)一次截?cái)嘁淮?/span>
int main ( ) { char *arr = "ABCD"; char *ret = strstr( arr,"BF" ); printf( "%c\n" , *ret ); system( "pause" ); return 0 ; }
4.高級(jí)查找字符串
查找一個(gè)字符串前綴
strspn(const char *str,const char *group);
strcspn(const char *str,const char *group);
group指定了一個(gè)或者多個(gè)字符。strspn返回str起始部分匹配group里任意字符的字符數(shù),如果str離包含空格和制表符那么這個(gè)函數(shù)將返回str其實(shí)部分空白字符的數(shù)目
而strcspn正好與之相反的計(jì)算了不匹配的字符數(shù)目一旦出現(xiàn)相等的就不統(tǒng)計(jì)了!!
下面的代碼將計(jì)算指向第一個(gè)非空白字符的指針的值:char *ptr=buffer+strspn(buffer,"\n\r\t\v");
查找標(biāo)記
找到第一個(gè)標(biāo)記并將它置成NULL 保存它的位置并且下次從上次保存的位置開始找下一個(gè)標(biāo)記。
提取表及
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。