版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第13章 字符串及字符串操作,在各種編程語言中,字符串的地位都十分重要,C語言中并沒有提供“字符串”這個特定類型,而是以特殊字符數(shù)組的形式來存儲和處理字符串,這種字符數(shù)組必須以空字符0結(jié)尾,因此,也將這種特定字符數(shù)組稱為C風(fēng)格字符串,本章討論字符串和字符串的一些處理函數(shù)。,13.1 C風(fēng)格字符串,C風(fēng)格字符串是字符數(shù)組的一種特例,這個“特”字體現(xiàn)在“以0(空字符,null character)結(jié)尾”,如何聲明創(chuàng)建一個C風(fēng)格字符串時,如何使用C風(fēng)格字符串,這是本節(jié)要解決的問題。,13.1.1 C風(fēng)格字符串的聲明,首先想到的方法是聲明一個字符數(shù)組,而后對其中元素初始化,不過要保證最后一個元素是空字
2、符0,即: char str=I, ,L,o,v,e, ,C,H,I,N,A,0; 還記得么?如果在數(shù)組聲明時沒有指定第1維的大小,編譯器將根據(jù)初始化表達(dá)式執(zhí)行決定數(shù)組的大小,對C風(fēng)格字符串來說,這是種不錯的方法,免得一個個字符去數(shù)。 上述聲明方式看上去很麻煩,要一個字母一個字母地用單引號包裹起來,還要記著最末尾的空字符0,實(shí)際上,在C語言中,還提供了另一種聲明C風(fēng)格字符串的方法使用字符串常量,如: char str=”I Love CHINA”;,13.1.2 C風(fēng)格字符串內(nèi)存中的表示,上面聲明的str中,C風(fēng)格字符串共有12個有效字符,但卻占據(jù)了13個內(nèi)存空間,編寫一段代碼來驗(yàn)證這個結(jié)論,
3、見示例。 代碼 C風(fēng)格字符串占據(jù)的內(nèi)存字節(jié)數(shù)SizeOfStr #include /*使用printf要包含的頭文件*/ #include void main(void)/*主函數(shù)*/ char sz=I Love CHINA;/*聲明一個C風(fēng)格字符串*/ printf(sz在內(nèi)存中的大小為:%d,sizeof(sz);/*輸出sz占據(jù)的內(nèi)存字節(jié)數(shù)*/ getch();/*等待,按任意鍵繼續(xù)*/ 輸出結(jié)果為: sz在內(nèi)存中的大小為:13,13.2 字符數(shù)組的輸入輸出,請注意:本節(jié)的標(biāo)題沒有寫“C風(fēng)格字符串的輸入輸出”,而是說“字符數(shù)組的輸入輸出”,實(shí)際上,C語言允許對字符數(shù)組進(jìn)行整體的輸入輸出
4、和元素訪問,并不會檢查其末尾是否為空元素,在本節(jié)學(xué)習(xí)中,讀者應(yīng)細(xì)心體會字符數(shù)組和C風(fēng)格字符串在輸入輸出等方面的不同。,13.2.1 字符數(shù)組可以進(jìn)行整體輸入輸出,普通數(shù)組不能進(jìn)行整體輸入輸出,必須以元素為單位進(jìn)行,而字符數(shù)組是個例外,來看一個例子,見示例: 代碼 字符串的整體輸入輸出StrInputOutput #include /*使用printf要包含的頭文件*/ #include void main(void)/*主函數(shù)*/ char sz=I Love CHINA;/*聲明一個C風(fēng)格字符串*/ printf(%sn,sz);/*對字符串進(jìn)行整體輸出*/ printf(請重新輸入一個字符
5、串,不多于12個字符n);/*提示用戶重新輸入一個字符串*/ scanf(%s,sz);/*讀取新的輸入*/ printf(修改后的字符串為:%sn,sz);/*整體輸出新的字符串*/ getch();/*等待,按任意鍵繼續(xù)*/ 輸出結(jié)果為: I Love CHINA 請重新輸入一個字符串,不多于12個字符 Hello World(鍵盤輸入) 修改后的字符串為:Hello,13.2.2 使用gets函數(shù)讀入整行輸入,在接收輸入時,空格和隨后的字符都被舍棄掉了,那有沒有一種方法能將空格和隨后的字符一塊讀入呢?有,C語言提供了gets函數(shù),見示例: 代碼 使用gets函數(shù)讀取一整行到字符數(shù)組中Fu
6、nctionGets #include /*使用printf要包含的頭文件*/ #include void main(void)/*主函數(shù)*/ char string 256;/*開辟一字符數(shù)組string*/ printf (Insert your full Name: n);/*提示用戶輸入*/ gets (string);/*使用gets函數(shù)讀取輸入*/ printf (Your Name is: %sn,string);/*輸出字符串*/ getch();/*等待,按任意鍵繼續(xù)*/ 輸出結(jié)果為: Insert your full Name: li kuan(鍵盤輸入) Your Nam
7、e is: li kuan,13.2.3 訪問字符數(shù)組中某個元素,字符數(shù)組首先是個數(shù)組,可以借助下標(biāo)訪問其中的單個字符,前面提到:在一個C風(fēng)格字符串內(nèi)部不能出現(xiàn)空字符,否則會將一個C風(fēng)格串截斷,下面的示例驗(yàn)證了這一說法: 代碼 訪問字符數(shù)組中的某個元素StrElement #include /*使用printf要包含的頭文件*/ #include void main(void)/*主函數(shù)*/ char sz=I Love CHINA;/*聲明一個C風(fēng)格字符串*/ printf(%sn,sz);/*對字符串進(jìn)行整體輸出*/ sz5=0;/*將字符串中第6個元素置為空字符*/ printf(修改后
8、的字符串為:%sn,sz);/*整體輸出新的字符串*/ getch();/*等待,按任意鍵繼續(xù)*/ 輸出結(jié)果為: I Love CHINA 修改后的字符串為:I Lov,13.2.4 更便捷的輸出使用puts函數(shù),調(diào)用puts()函數(shù)實(shí)現(xiàn)字符串的輸出,其調(diào)用形式為: puts(字符數(shù)組); 該函數(shù)的功能是將字符數(shù)組起始地址開始的一個字符串(以0結(jié)束的字符序列)輸出到終端,并將字符串結(jié)束標(biāo)志0轉(zhuǎn)化成n,自動輸出一個換行符。 舉個簡單的例子: char sz = InLOVE C+!; puts(sz); 輸出結(jié)果: I LOVE C+!,13.3 字符串處理函數(shù),作為一種特殊的數(shù)組,字符數(shù)組所能
9、享受的“特殊待遇”就是允許整體輸入和輸出,數(shù)組操作的其他限制對字符數(shù)組同樣成立,如不允許使用一個數(shù)組給另一個數(shù)組賦值,不允許整體比較兩個數(shù)組,不允許對兩個進(jìn)行整體的算術(shù)操作,下列用法都是錯誤的: char x10,y10=”123456789”; x=”987654321”; /*錯誤*/ x=y;/*錯誤*/ if(x y)/*錯誤*/ x+=y;/*錯誤*/ 如果要實(shí)現(xiàn)這些特定的功能,必須以數(shù)組元素,此處是字符,為基本單位來實(shí)現(xiàn),舉例來說,編寫一個函數(shù)計算字符串中字符個數(shù)的函數(shù),如下: int strlenOwn(const char* psz)/*const使得字符數(shù)組不被修改,指針ps
10、z可修改*/ int len=0; while( *(psz+) ) len+; return len; ,13.3.1 理解:數(shù)組名是常指針,在繼續(xù)書寫示例調(diào)用上述strlenOwn函數(shù)之前,先來理解一個重要的概念:數(shù)組名是常指針,很多教科書中說,數(shù)組名是指向數(shù)組第1個元素的指針,這種說法欠妥。對一維數(shù)組來說,這個說法成立,但對高維數(shù)組,首先要確定的是數(shù)組名這個指針是什么類型的。 拋開數(shù)組名是什么類型的值不說,如果用數(shù)組名為一個指針賦值,該指針的值等于第1個元素的地址。 先來看最簡單的情況: int num10=0; int *p1=num; int* p2=num+1; 此時,數(shù)組名num
11、可看成是int型的常指針,其值為其中第1個元素的地址,使用數(shù)組名num為p1賦值時,p1指向數(shù)組中的第1個元素num0,p2指向num1。 對二維數(shù)組來說,情況略有不同: int num34=0; int* p1=num; int* p2=num+1;,13.3.2 strlen函數(shù)與size_t,strlen函數(shù)返回的是字符串的長度,即字符串中的實(shí)際字符數(shù)目,末尾的空字符不計數(shù),返回類型為size_t,讀者也許對size_t類型比較陌生,該類型定義于標(biāo)準(zhǔn)頭文件stddef.h中: typedef unsigned int size_t; 在后續(xù)章節(jié)中會對typedef進(jìn)行詳細(xì)介紹,此處可以理
12、解為一種等價關(guān)系,即size_t是無符號整型unsigned int的別名。 在使用size_t類型時,有一點(diǎn)需要特別注意,假設(shè)變量A和B都為size_t類型,則下述關(guān)系式恒成立: A B 0 這樣,不能通過將兩個size_t類型變量做差來比較大小,因此,不能通過strlen函數(shù)返回的字符串長度做差比較到底哪個字符串更長一些,來看一段示例:,13.3.3 字符串復(fù)制函數(shù)strcpy,strcpy函數(shù)用于將一個C風(fēng)格字符串(源串)復(fù)制給另一個C風(fēng)格字符串(目的串),在使用strcpy函數(shù)有一點(diǎn)要注意,目的字符數(shù)組和源字符數(shù)組的大小問題,避免將長串復(fù)制給短串,這會導(dǎo)致數(shù)組越界錯誤。 來看一段str
13、cpy函數(shù)的使用范例,見: 代碼 將一個字符串復(fù)制給另一個字符串StrcpySample #include /*使用printf要包含的頭文件*/ #include #include void main(void)/*主函數(shù)*/ char str1256=0;/*開辟一字符數(shù)組str1*/ char str2256=0;/*開辟一字符數(shù)組str2*/ printf (請輸入第1個字符串: n);/*提示用戶輸入第1個字符串*/ gets (str1);/*使用gets函數(shù)讀取一行輸入*/ strcpy(str2,str1);/*將第1個字符串復(fù)制給第2個字符串*/ printf(第2個字符串為
14、:n%s,str2);/*輸出第2個字符串*/ getch();/*等待,按任意鍵繼續(xù)*/ ,13.3.4 字符串比較函數(shù)strcmp,strcmp函數(shù)用于對兩個C風(fēng)格字符串進(jìn)行比較,此處的比較不是比較兩個字符串的長度,而是逐個比較字符的ASCII碼,舉例來說,如果字符串1以字母A開頭,而字符串2以B開頭,則不論兩個字符串長度如何,不論兩個字符串后續(xù)字串是什么,字符串2“大于”字符串1成立(B的ASCII碼66大于A的ASCII碼65),如果打頭字符相同,則比較第2個字符,依此類推,如果第2個字符相同,則比較第3個字符 如果出現(xiàn)諸如“ABCD”和“ABCD123”這樣的情況,長度長的字符串“大
15、于”長度短的字符串。換言之,只有兩個字符串長度相同、每個字符相等時,才稱兩個字符串相等。 對漢字來說,比較的是內(nèi)碼,關(guān)于漢字內(nèi)碼的相關(guān)介紹,感興趣的讀者可自行查閱相關(guān)資料。 strcmp函數(shù)的原型為: int strcmp(字符串1,字符串2);,13.3.5 字符串連接函數(shù)strcat,字符串連接函數(shù)的原型為: char* strcat(字符串1,字符串2); 該函數(shù)會將字符串2附在字符串1后面,這樣,字符串1的長度會有所增加,返回的指針指向字符串1。讀者也許會有疑問:是否要求字符串1所在的字符數(shù)組有足夠的內(nèi)存空間來容納字符串2。 原則上,答案為“是,字符串1所在的字符數(shù)組應(yīng)有足夠的內(nèi)存空間
16、來容納字符串2”,否則會出現(xiàn)內(nèi)存越界的錯誤,這和前面strcpy函數(shù)中要求目的字符串的長度要大于源字符串的長度是一回事。 實(shí)際上,即使兩個條件不滿足,“大部分情況下”,strcat函數(shù)和strcpy函數(shù)的執(zhí)行并不會出錯,這是因?yàn)樽兞吭趦?nèi)存中的位置很稀疏,如果字符數(shù)組后的一塊內(nèi)存并沒有被其他變量等占用,程序不會出錯,但如果該塊內(nèi)存不巧已經(jīng)被分配,程序可能因此而崩潰。,13.3.6 全轉(zhuǎn)換為大寫形式,在某些場合,要求輸入一個字符串,如果是大小寫無關(guān)的,問題就來了,比如,在大小寫無關(guān)意義下,“AB”、“ab”、“aB”、“Ab”都是等價的,這僅僅是兩個字母的情況,如果字母更多,情況更復(fù)雜,在程序中去
17、一一判斷也很不現(xiàn)實(shí),為此,C標(biāo)準(zhǔn)庫提供了字符串處理函數(shù)strupr,用于將字符串中所有的字母都轉(zhuǎn)換成大寫形式,其原型為; char* strupr(字符串); 函數(shù)返回指向字符串的指針,來看一段示例:,13.3.7 鏈?zhǔn)讲僮?前面介紹的幾個函數(shù)中,strcpy函數(shù)、strcat函數(shù)和strupr函數(shù)的返回類型均為char*型,這可以方便地進(jìn)行鏈?zhǔn)讲僮鳎e個例子,中采用了下述語句先對str中的字符大寫化,而后再比較其與“PASS1234”是否相同: strupr(str);/*將輸入的字符串轉(zhuǎn)成大寫形式*/ if(strcmp(str,PASS1234) = 0)/*如果兩個字符串相等*/ 更為簡潔的寫法是: f(strcmp( strupr ( str ),PASS1234) = 0)/*如果兩個字符串相等*/ ,13.4 小結(jié),在程序設(shè)計中,字符串的使用十分廣泛,本章重點(diǎn)介紹了C風(fēng)格字符串的相關(guān)內(nèi)容,C風(fēng)格字符串是種特殊的一維字符數(shù)組:除存放字符串中的各個字符外,C風(fēng)格字符串最后一個字符為空字符0。聲明C風(fēng)格字符串時,既可用字符串常量為其中元素初始
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中國西裝套行業(yè)市場調(diào)查研究及投資戰(zhàn)略研究報告
- 2025年輕型卡車空調(diào)裝置項目投資可行性研究分析報告
- 特教情緒行為課程設(shè)計
- 課程設(shè)計水利本
- 車床課程設(shè)計報告
- 2024工藝美術(shù)品及收藏品零售行業(yè)分析報告
- 煉油廢水處理課程設(shè)計
- 2025年收緊機(jī)行業(yè)深度研究分析報告
- 2025年度企業(yè)間應(yīng)收賬款融資合同
- 2025勞動合同熱線范文
- 綿陽市高中2022級(2025屆)高三第二次診斷性考試(二診)歷史試卷(含答案)
- 廠級安全培訓(xùn)資料
- 中國藥科大學(xué)《藥物化學(xué)》教學(xué)日歷
- 露天礦山課件
- 經(jīng)濟(jì)效益證明(模板)
- 銀行卡凍結(jié)怎么寫申請書
- 果樹蔬菜病害:第一章 蔬菜害蟲
- 借條借款合同帶擔(dān)保人
- 人工地震動生成程序
- SSB變槳系統(tǒng)的基礎(chǔ)知識
- 大五人格量表(revised)--計分及解釋
評論
0/150
提交評論