版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第七章第七章 字符數(shù)組與字符串字符數(shù)組與字符串4本章主要內(nèi)容123字符型數(shù)據(jù)字符數(shù)組與字符串常用字符串函數(shù)常用字符串函數(shù)字符串應(yīng)用舉例字符串應(yīng)用舉例5字符串?dāng)?shù)組字符串?dāng)?shù)組7.1 字符型數(shù)據(jù)n7.1.1 字符型數(shù)據(jù)的存儲(chǔ)n7.1.2 轉(zhuǎn)義序列n7.1.3 字符型數(shù)據(jù)的輸入輸出7.1.1 字符數(shù)據(jù)的存儲(chǔ)n字符型數(shù)據(jù)的存儲(chǔ)方法根據(jù)計(jì)算機(jī)的不同而不同,因?yàn)椴煌瑱C(jī)器可能有不同的字符集。當(dāng)今最常用的字符集是ASCII(美國信息交換標(biāo)準(zhǔn)碼)字符集,它用7個(gè)二進(jìn)制位表示128個(gè)字符。在ASCII碼中,數(shù)字0-9用01100000111001碼來表示,字母A-Z用10000011011010表示。值值符號(hào)符號(hào)值
2、值符號(hào)符號(hào)值值符號(hào)符號(hào)0空字符44,9132空格45-9233!46.933447/9435#48 570 995-36$58:9637%59;97 122a z38&6012541)63?12642*64127DEL43+65 90A Z字符數(shù)據(jù)類型占 8 位內(nèi)存signed或 unsignedSigned-128 至 +127 unsigned 0 至 255 在C語言中,字符和整數(shù)之間存在著密切的關(guān)系。C語言把字符當(dāng)成小整數(shù)進(jìn)行處理。字符型溢出問題n輸入一個(gè)英文小寫字符和正整數(shù)k(k26),將英文字母加密并輸出。n加密思想:將每個(gè)字母c加一個(gè)序數(shù)k,即用它后面的第k個(gè)字母代替,變
3、換公式:c=c+k。如果字母為z,則后一個(gè)字母是a,也就是字母表形成一個(gè)圓。解決問題: 字符加密#includeint main()char ch;int k;scanf(%c %d, &ch, &k);ch = ch + k; /可能類型溢出 if(ch z)ch = ch - 26;printf(%cn, ch);return 0;源程序7-1:char類型溢出輸入小于g的字符和任意k(1-25),運(yùn)行結(jié)果正確當(dāng)輸入z 6 或 g 25 , 結(jié)果錯(cuò)誤原因是char類型溢出signed char: -128 至 +127z+6的值是的值是128超出超出char表表示范圍示范圍
4、#includeint main()unsigned char ch;int k;scanf(%c %d, &ch, &k);ch = ch + k; if(ch z)ch = ch - 26;printf(%cn, ch);return 0;解決方法1:使用unsigned charunsigned char: 0 至 255一個(gè)英文小寫字符和正整數(shù)k(k26)的和,不會(huì)超出這個(gè)范圍#includeint main()char ch;int k;scanf(%c %d, &ch, &k); if(ch + k z) ch = ch + k - 26; else
5、 ch = ch + k;printf(%cn, ch);return 0;解決方法2:分類處理,避免溢出若ch + k z,則減去26后存儲(chǔ),避免存儲(chǔ)時(shí)溢出在計(jì)算ch + k 的過程中不會(huì)溢出,因?yàn)橐驗(yàn)榫幾g器把算術(shù)運(yùn)算中涉及的char類型都提升為int類型#includeint main()int k = 123456 * 123456 / 123456; printf(%dn, k); return 0;注意計(jì)算過程中的溢出 其實(shí)有更多的類型溢出是發(fā)生在計(jì)算階段,例如表達(dá)式:k = 123456 * 123456 / 123456, 雖然結(jié)果不會(huì)超出int范圍,但在計(jì)算過程中,中間結(jié)果超出
6、int范圍,也將發(fā)生溢出。該程序無法得到正確結(jié)果,是因?yàn)橛?jì)算 123456 * 123456的結(jié)果超出了int類型的表示范圍。避免此類問題的方法:1、選擇表示范圍更大的數(shù)據(jù)類型2、先除后乘,但要解決好整數(shù)除法帶來的問題。希望輸出:Jack: Youre my best friend代碼:printf(Jack: Youre my best friendn);輸出單引號(hào)用,輸出雙引號(hào)用 。C語言提供了轉(zhuǎn)義序列來表示特殊字符,有字符轉(zhuǎn)義序列和數(shù)字轉(zhuǎn)義序列7.1.2 轉(zhuǎn)義序列如何輸出雙引號(hào)和單引號(hào)?字符 轉(zhuǎn)義序列轉(zhuǎn)義序列轉(zhuǎn)義序列名稱名稱描述描述a 警告產(chǎn)生一則警告。b 退格將光標(biāo)回退一格。f 換頁將
7、光標(biāo)移到下一頁的第一格。n 換行將光標(biāo)移到下一行的第一格。r 回車將光標(biāo)移到當(dāng)前行的第一格。t 水平制表 將光標(biāo)移到下一個(gè)水平制表位置。v 垂直制表將光標(biāo)移到下一個(gè)垂直制表位置。 單引號(hào)產(chǎn)生一個(gè)單引號(hào)。 雙引號(hào)產(chǎn)生一個(gè)雙引號(hào)。? 問號(hào)產(chǎn)生一個(gè)問號(hào)。反斜線產(chǎn)生一條反斜線。0 空產(chǎn)生一個(gè)空字符。 字符轉(zhuǎn)義序列使用起來很容易,但數(shù)量有限,并沒有包含所有無法打印的ASCII字符。C語言提供了數(shù)字轉(zhuǎn)義序列。所有ASCII碼字符,都可以用數(shù)字轉(zhuǎn)義序列來表示。可以用八進(jìn)制數(shù)或十六進(jìn)制來書寫轉(zhuǎn)義字符。n八進(jìn)制轉(zhuǎn)義序列:由和跟隨其后的最多含有三位數(shù)字的八進(jìn)制數(shù)組成。例如,a的ASCII碼對(duì)應(yīng)的八進(jìn)制是141,則
8、數(shù)字轉(zhuǎn)義序列141就表示a。n十六進(jìn)制轉(zhuǎn)義序列:由x和跟隨其后的十六進(jìn)制數(shù)組成。例如,a的ASCII碼對(duì)應(yīng)的十六進(jìn)制是61,則數(shù)字轉(zhuǎn)義序列x61就表示a。數(shù)字 轉(zhuǎn)義序列數(shù)字轉(zhuǎn)義序列(部分)八進(jìn)制轉(zhuǎn)義序列八進(jìn)制轉(zhuǎn)義序列十六進(jìn)制轉(zhuǎn)義序列十六進(jìn)制轉(zhuǎn)義序列描述描述7 x7響鈴10 x8退格鍵12 x0C換頁鍵10 x0A換行鍵40 x20空格60 x300101x41A141x61aprintf(“a10bn”); /輸出輸出: b, 因?yàn)檗D(zhuǎn)義序列因?yàn)檗D(zhuǎn)義序列10是是 退格鍵退格鍵printf(“14110142n”); /輸出輸出: b, 含義同上含義同上7.1.3 字符數(shù)據(jù)的輸入輸出nscanf(
9、)函數(shù)和getchar()都可以用來讀入單個(gè)字符。但與整型和實(shí)型數(shù)據(jù)的讀入不同的是,所有輸入都是合法的字符輸入,包括空格、回車等空白符。若有以下輸入語句:scanf(%c%c%c, &ch1, &ch2, &ch3); 如果輸入為:a b c結(jié)果是:ch1值為a,ch2值為 ,ch3值為b。 如何跳過空白符 如果在程序中需要先讀入一個(gè)整數(shù)存入變量n, 然后讀入一個(gè)字符存入變量ch,輸入格式如下:5M該如何用scanf()函數(shù)實(shí)現(xiàn)呢?若寫為: scanf(%d, &n); scanf(%c, &ch);存入ch中的將是數(shù)字5之后的回車符。解決方法解決方法解
10、決方法1:加一個(gè)讀入語句將數(shù)組5之后的回車處理掉: scanf(%d, &n); getchar(); /* 將緩沖區(qū)中的回車讀入*/ scanf(%c, &ch);解決方法解決方法2:為了強(qiáng)制scanf()函數(shù)在讀入字符前跳過空白符,需要在格式串中的%c之前加上一個(gè)空格: scanf(%d, &n); scanf( %c, &ch);scanf格式串中的空白意味著“跳過零個(gè)或多個(gè)空白字符”。7.1.4 字符處理函數(shù)前面已經(jīng)講過如何把小寫字母轉(zhuǎn)換成大寫字母:if(ch = a & ch = z) ch = ch - 32;其實(shí)可以使用庫函數(shù)toupper
11、()來完成上述操作,即ch = toupper(ch);toupper(ch)函數(shù)會(huì)檢測(cè)參數(shù)ch是否是小寫字母,如果是,它會(huì)把ch轉(zhuǎn)換成大寫字母返回,否則原樣返回參數(shù)的值。tolower(ch)會(huì)把ch轉(zhuǎn)換成小寫字母返回isdigit(ch)用來判斷一個(gè)字符ch是否是數(shù)字isalpha(ch)用來判斷一個(gè)字符是否是字母,重寫程序4-13:字符分類統(tǒng)計(jì)letter = digit = other = 0;while(ch = getchar(), ch != n) if( isalpha(ch) ) /*若ch是字母*/ letter+; else if( isdigit(ch) ) /*若ch
12、是數(shù)字*/ digit+; else /*其他字符*/ other+;ctype.h頭文件中的部分函數(shù)函數(shù)功能功能tolower()轉(zhuǎn)換為小寫字母toupper()轉(zhuǎn)換為大寫字母islower()判斷是否是小寫字母isupper()判斷是否是大寫字母isalpha()判斷是否是小寫或大寫字母isdigit()判斷是否是十進(jìn)制數(shù)字(0-9)isxdigit()判斷是否是十六進(jìn)制數(shù)字(0-9,a-f,A-F)isblank()判斷是否是空白字符(空格,t)7.2 字符數(shù)組與字符串char a = W;char b = a;char c = n;char d = g;char e = L;char
13、f = i;如何讓程序存儲(chǔ)我的姓名?WangLichar name15 = W, a, n, g, L, i; 用若干個(gè)字符用字符數(shù)組用字符串char name15 = “Wang Li”;7.2.1統(tǒng)計(jì)空格解決問題:輸入一行字符(字符個(gè)數(shù)不多于80),統(tǒng)計(jì)其中空格的個(gè)數(shù)解題思路:(1)定義字符數(shù)組 str81;(2)讀入字符串若字符串確定不含空格,可以用scanf(“%s”,&str);若可能含有空格,用gets(str);(3)掃描整個(gè)字符串(不需要知道字符個(gè)數(shù))#include int main() char str81; int i, count = 0; printf(n 請(qǐng)
14、輸入一行字符:n ); gets(str); for(i = 0; stri != 0; i+) if(stri = ) count+; printf(n 其中的空格總數(shù)為 %d n ,count); 在循環(huán)執(zhí)行時(shí),掃描整個(gè)數(shù)組以統(tǒng)計(jì)出空格 的數(shù)量,直到遇到字符 0。7.2.2 一維字符數(shù)組與字符串一維字符數(shù)組的定義、引用、初始化與其他類型的一維數(shù)組一樣。char str80; 定義一個(gè)含有80個(gè)字符型元素的數(shù)組str char t5 = H, a, p, p, y;初始化數(shù)組 t t0 t1 t4tHappy作為普通數(shù)組,可以用如下循環(huán)輸出數(shù)組t的所有元素for(i = 0; i 5; i+
15、) putchar( ti );但是,”Happy”作為一個(gè)單詞,如果能整體輸入輸出,顯然更方便一些!字符串常量n字符串常量是雙引號(hào)括起的任意字符序列HelloWorld0Hello WorldWangPingPlease enter your full name: “Hello!n字符串常量中可以包含轉(zhuǎn)義序列字符串結(jié)束符字符串的字符串的有效長度有效長度:有效字符的個(gè)數(shù):有效字符的個(gè)數(shù)字符串的存儲(chǔ)char s80 = Happy;字符串遇 0 結(jié)束第一個(gè) 0 前面的所有字符和 0 一起構(gòu)成了字符串 Happy”0 之后的其他數(shù)組元素與該字符串無關(guān) s0 s1 s5s H a p p y 0 0
16、 0 字符串由有效字符和字符串結(jié)束符 0 組成 字符串與字符數(shù)組n在語言中沒有專門的字符串變量,通常用一個(gè)字符數(shù)組來存放一個(gè)字符串n字符數(shù)組和字符串的區(qū)別是:字符串的末尾有一個(gè)空字符 0字符串可按如下方式聲明并初始化:char name15 = W, a, n, g, L, i, 0;char name15 = WangLi;char password = 12345678;手工加入一個(gè)空字符系統(tǒng)將自動(dòng)加入一個(gè)空字符省略數(shù)組大小,系統(tǒng)自動(dòng)計(jì)算,大小為后面的字符總數(shù)加1,最后一個(gè)元素存入一個(gè)空字符。 后兩種為數(shù)組賦初值的方式,本質(zhì)上與第一種方式本質(zhì)相同,只是寫成了我們更習(xí)慣的樣子。方法1:用%s
17、整體輸入輸出char name10;scanf(%s, name);printf(%s, name);格式描述串中使用轉(zhuǎn)換字符串“%s”Wang LiWang0使用 scanf 時(shí),不能輸入空格Wang空格是%s輸入結(jié)束的標(biāo)志7.2.3 字符串的輸入輸出方法2:用gets和puts函數(shù)char name10;gets(name);puts(name);W angLi0W a n g LiWang Li從鍵盤上讀入一個(gè)完整的行,存入字符數(shù)組name。并在最后添加字符串結(jié)束標(biāo)識(shí)0把字符數(shù)組中的字符串輸出到顯示器。使用 gets函數(shù)允許輸入空格7.3 常用字符串函數(shù)7.3.1 定義在頭文件strin
18、g.h中的字符串函數(shù)(1)strlen: 求字符串長度(2)strcpy:字符串復(fù)制(賦值)(3)strcmp:字符串比較(4)strcat:字符串合并(5)strrev: 字符串逆置(1) 求字符串長度 strlen( )調(diào)用格式:調(diào)用格式:功能:功能:測(cè)試字符串長度。函數(shù)值就是測(cè)試字符串長度。函數(shù)值就是strstr中字符的中字符的個(gè)數(shù)。個(gè)數(shù)。例如:例如:char str10 = China;printf(%d, strlen(str);或或printf(%d, strlen(China);printf(%d, strlen(161bcdn);(2)字符串復(fù)制函數(shù) strcpy( )調(diào)用格式
19、:調(diào)用格式:功能:將功能:將str2str2中的字符串復(fù)制到中的字符串復(fù)制到str1str1數(shù)組中。數(shù)組中。思考:這樣賦值s1 = Beijing ; 或 s1 = s2;可以嗎?為什么?s1的結(jié)果的結(jié)果例如:例如:char s110,s2 = Beijing;char s110,s2 = Beijing; strcpy(s1,s2); strcpy(s1,s2);或:或:strcpy(s1,Beijing);strcpy(s1,Beijing);字符串的賦值需要通過strcpy實(shí)現(xiàn)char str110 = “China”;正確char str110 ;str1 = “China”;錯(cuò)誤改為
20、:char str110 ;strcpy(str1, “China”);char str110, str2 = “China”;str1 = str2;改為:char str110 , str2 = “China”;strcpy(str1, str2);為什么不允許這樣賦值?因?yàn)閿?shù)組名是一個(gè)常量,代表數(shù)組的首地址,常量不可以被賦值,其值不可改變錯(cuò)誤對(duì)兩個(gè)字符串自左至右逐個(gè)字符相比(按ASCII碼值大小比較),直到出現(xiàn)不同的字符或遇到0為止。如果全部字符相同,則認(rèn)為相等;若出現(xiàn)不相同的字符,則以第一個(gè)不相同的字符的比較結(jié)果為準(zhǔn)。(1返回0(2)返回一個(gè)正整數(shù)(3),返回一個(gè)負(fù)整數(shù)。 str1 s
21、tr2“cat” “fan”“Abd” “abd”“abcde” “abc”“abc” “abc”(3)字符串比較函數(shù) strcmp( )調(diào)用格式:調(diào)用格式:比較str1和str2的大小,若前者大則返回一個(gè)正整數(shù),若后者大則返回一個(gè)負(fù)整數(shù),若兩者相等,則返回0。=strcmp(str1, str2)0strcmp(str1, str2)0strcmp(str1, str2)=0注意: 比較兩個(gè)字符串的大小只能使用此函數(shù),而不能使用“”、“”、“=”等關(guān)系運(yùn)算符。(4) 字符串連接函數(shù) strcat( )把把str2str2中的字符串連接到中的字符串連接到str1str1字符串的后面,結(jié)果字符串
22、的后面,結(jié)果放在放在str1str1數(shù)組中數(shù)組中. .例如:例如:char str121= beijing and ;char str121= beijing and ;char str2 = shanghai;char str2 = shanghai;strcat(str1,str2);strcat(str1,str2);printf(%s,str1);printf(%s,str1);(5) 字符串逆置函數(shù) strrev( ) 字符串字符串strstr的所有字符的順序顛倒過來的所有字符的順序顛倒過來( (不包括空字不包括空字符符NULL)NULL)。例如:例如:char str10=hell
23、o;char str10=hello;strrev( str );strrev( str );printf(%s,str);printf(%s,str);注意:注意:strrevstrrev()()函數(shù)不是標(biāo)準(zhǔn)函數(shù)不是標(biāo)準(zhǔn)C C的庫函數(shù),某些編的庫函數(shù),某些編譯器沒有包含該函數(shù)的定義,此時(shí)需要自己實(shí)現(xiàn)譯器沒有包含該函數(shù)的定義,此時(shí)需要自己實(shí)現(xiàn)strrevstrrev()()函數(shù)。函數(shù)。字符串逆置功能的實(shí)現(xiàn)str0 i數(shù)組元素?cái)?shù)組元素 內(nèi)容內(nèi)容 下標(biāo)下標(biāo)str1 strlen-1 j void StrRev(char str) i = 0; j = len 1; while(i不相等j) str
24、i與strj互換內(nèi)容 下標(biāo)i從前向后依次增加 下標(biāo)j從后向前依次減小 void StrRev(char str) int i, j, len; len = strlen(str); for(i = 0, j = len-1; i j; i+, j-) char temp = stri; stri = strj; strj = temp; 最大字符串n 解決問題:最大字符串。解決問題:最大字符串。n輸入正整數(shù)n(0 n = 10),然后輸入n個(gè)字符串,輸出字典序最大的字符串。運(yùn)行效果如下:請(qǐng)輸入字符串個(gè)數(shù):3請(qǐng)輸入3個(gè)字符串:testcathello最大字符串: test思路:(1) 讀入n(2
25、) 將max置為最小字符串(空串)。(3) 循環(huán)n次,每次讀入一個(gè)字符串str,若str大于max,則將str存入max(4) 輸出字符串max/* 程序7-3 */char maxN = ;scanf(%d, &n);getchar();for(i = 1; i 0 ) strcpy(max, str);puts(max);getsgets函數(shù)的讀取規(guī)則函數(shù)的讀取規(guī)則 只要gets遇到換行符,即便它是輸入的第一個(gè)字符,gets也會(huì)停止讀入并返回。如果輸入的第一個(gè)字符就是換行符,則字符串將被置為空串。 所以上例中使用gets()前要清空緩沖區(qū)中的回車。方法方法1 1: getcharg
26、etchar() () getchar()讀入緩沖區(qū)中剩余的回車 如上例中,用getchar()讀入之前整數(shù)之后的回車。缺點(diǎn)是只能讀入1個(gè)字符方法方法2 2:scanfscanf(“ ”) 用scanf格式串中的空白符跳過一個(gè)或多個(gè)空白符,直到遇到非空白符。方法方法3 3: fflushfflush( (stdinstdin) ) 清空輸入緩沖區(qū),通常是為了確保不影響后面的數(shù)據(jù)讀取。是包含在stdio.h中的非標(biāo)準(zhǔn)庫文件,不是所有編譯器都支持。 課堂練習(xí):輸入n個(gè)字符串n最長字符串:輸入n和n個(gè)字符串,輸出其中最長的字符串。char maxN = ;scanf(%d, &n);scan
27、fscanf( );for(i=1; i strlen(max) strcpy(max, str);puts(max);scanf(%d , &n);gets函數(shù)的返回值getsgets函數(shù)的返回值:函數(shù)的返回值:1.正常讀入(未遇到文件結(jié)尾)(注意,讀入空串也是正常讀入),則返回字符串,即返回字符串首地址,char*類型;2.遇到文件結(jié)尾,返回NULL;NULL是stdio中定義的常量0getsgets函數(shù)的危險(xiǎn)性:函數(shù)的危險(xiǎn)性: gets 函數(shù)沒有檢測(cè)緩沖區(qū)大小的問題,用戶無法指定其一次最多讀入多少字節(jié)的內(nèi)容,所以可以隨意輸入很長的數(shù)組,內(nèi)容可以寫入內(nèi)存。當(dāng)年不少的黑客攻擊都是利用
28、此漏洞。輸入多個(gè)字符串,直到文件結(jié)束n最大字符串:輸入若干個(gè)字符串,每個(gè)占一行,輸出其中最大的字符串。char maxN = ;while( gets(str) ) if( strcmp(str, max) 0) strcpy(max, str);puts(max);輸入多個(gè)字符串,以特殊輸入結(jié)束n最大字符串:輸入若干個(gè)字符串,每個(gè)占一行,若輸入”#”表示輸入結(jié)束。輸出其中最大的字符串。char maxN = ;while( gets(str) , strcmp(str, “#”) !=0 ) if( strcmp(str, max) 0) strcpy(max, str);puts(max)
29、;7.3.2 stdlib.h中字符串轉(zhuǎn)換函數(shù)(1)atof: 將一個(gè)字符串轉(zhuǎn)換為一個(gè)double類型的浮點(diǎn)數(shù)(2)atoi:將一個(gè)字符串轉(zhuǎn)換為一個(gè)int類型的整數(shù)(3)atol:將一個(gè)字符串轉(zhuǎn)換為一個(gè)long int類型的整數(shù)(4)itoa: 將一個(gè)整數(shù)轉(zhuǎn)換為一個(gè)字符串注意:這幾個(gè)函數(shù)雖然應(yīng)用廣泛,但不是標(biāo)準(zhǔn)注意:這幾個(gè)函數(shù)雖然應(yīng)用廣泛,但不是標(biāo)準(zhǔn)C C的的庫函數(shù),某些編譯器沒有包含該函數(shù)的定義,此時(shí)庫函數(shù),某些編譯器沒有包含該函數(shù)的定義,此時(shí)需要自己定義這些函數(shù)。需要自己定義這些函數(shù)。(1)字符串轉(zhuǎn)換為一個(gè)浮點(diǎn)數(shù) atof( )調(diào)用格式調(diào)用格式: 功能功能:將一個(gè)字符串轉(zhuǎn)換為一個(gè)doubl
30、e類型的浮點(diǎn)數(shù),函數(shù)值即為該浮點(diǎn)數(shù) 函數(shù)丟棄前面的空白字符直到遇到第一個(gè)非空白字符。從這個(gè)字符開始得到盡可能多的字符構(gòu)成一個(gè)有效的浮點(diǎn)數(shù),直到遇到非數(shù)字,最后一個(gè)數(shù)字后面的字符串的其他部分被忽略。printf(lfn, atof(990.0n ) );printf(lfn, atof( 990.0adfn ) );printf(lfn, atof(“a990.0n ) );(2)字符串轉(zhuǎn)換為一個(gè)int數(shù)據(jù) atoi( )調(diào)用格式調(diào)用格式: 功能功能:將一個(gè)字符串轉(zhuǎn)換為一個(gè)int類型的整數(shù),函數(shù)值即為該整數(shù)printf(lfn, atoi(990.99 ) );printf(lfn, atoi(
31、 990abcd ) );printf(lfn, atoi(a990 ) );printf(lfn, atoi( 9901234567 ) );(3)整數(shù)轉(zhuǎn)換為字符串itoa( )調(diào)調(diào)用格式用格式: itoa( d, str, r);功能功能:將一個(gè)整數(shù)d,轉(zhuǎn)換為r進(jìn)制的數(shù),存入字符串str,itoa(13, str, 2);puts(str);itoa(100, str, 8);puts(str);輸出一個(gè)整數(shù)n和它的逆序數(shù)的和函數(shù)原型:函數(shù)原型: int InvAdd(int n); int InvAdd(int n);該函數(shù)返回該函數(shù)返回n n和和n n的逆序數(shù)的和的逆序數(shù)的和intin
32、t InvAddInvAdd( (intint n) n) char char strstrN;N; itoaitoa(n, (n, strstr, 10); , 10); /把把n n轉(zhuǎn)換為字符串轉(zhuǎn)換為字符串strstr strrevstrrev( ( strstr); ); /逆置逆置strstr return n + return n + atoiatoi( (strstr); ); /返回返回 n n 和逆序數(shù)的和和逆序數(shù)的和 7.3.3 stdio中字符串函數(shù)sprintf(str, %d ,n);功能是把格式化的數(shù)據(jù)寫入字符串 str中。 sscanf(str, %d , &
33、;n);功能是從字符串str中進(jìn)行格式讀入/ /* *strstr中是中是1818位身份證,該函數(shù)輸出對(duì)應(yīng)生日位身份證,該函數(shù)輸出對(duì)應(yīng)生日* */ /intint PntBirthdayPntBirthday(char (char strstr) sscanf(str, %*6d%4d%2d%2d , &y, &m, &d); printf( %d年%d月%d日n , y, m, d); 水仙花數(shù)的判斷#include int main(void)char str10;int n, a, b, c;gets(str); /* 將輸入存入字符串*/sscanf(str,
34、“%d”, &n); /* 作為一個(gè)三位數(shù)讀入*/sscanf(str, “%1d%1d%1d”, &a, &b, &c); /* 三個(gè)一位數(shù)*/ if(n = a*a*a + b*b*b + c*c*c) printf(yesn); else printf(non); return 0;使用sscanf(),分析各位數(shù)字,實(shí)現(xiàn)水仙花數(shù)的判斷Super primeSuper prime是指一個(gè)k位的正整數(shù),它的前一位,前兩位,.,前k位都是素?cái)?shù)。函數(shù)原型:函數(shù)原型: int IsSuperPrm(int n); int IsSuperPrm(int n);若若n
35、 n是是Super prime,該函數(shù)該函數(shù)1 1,否則返回,否則返回0 0/* 若n是Super prime 數(shù)返回1,否則返回0 */int IsSuperPrm(int n) 將n轉(zhuǎn)換為字符串str for i=1,2, k 讀取str的前i個(gè)字符,并轉(zhuǎn)換為整數(shù),存入num; 若num不是素?cái)?shù),返回0; 返回1;sprintf(str, %d, n); if( IsPrime( num ) = 0) return 0;num = GetNum(str, i);將數(shù)值轉(zhuǎn)換為字符串,方便處理將數(shù)值轉(zhuǎn)換為字符串,方便處理/ /* *將將strstr的前的前n n位轉(zhuǎn)換為整數(shù)位轉(zhuǎn)換為整數(shù)* */
36、 /GetNum(char str, int n) int i, d = 0; for(i = 0; i n; i+) d = d * 10 + stri 0; return d; int IsSuperPrm(int n) int i, k, num; char strN, curN; sprintf(str, %d, n); k= strlen(str); for(i = 1; i = k; i+) GetNum(str, i); if( IsPrime( num ) = 0) return 0;return 1;/ /* *將將strstr的前的前n n位轉(zhuǎn)換為整數(shù)位轉(zhuǎn)換為整數(shù)* */
37、/GetNum(char str, int n) char curN; strncpy(cur, str, n); curn = 0; return atoi(cur); /遞歸實(shí)現(xiàn)int IsSuperPrm(int n) if( IsPrime(n) = 0) return 0; else if( n 0) if( IsPrime(n) = 0) return 0; n = n/10; return 1;7.4 字符串應(yīng)用舉例7.4.1統(tǒng)計(jì)單詞個(gè)數(shù)7.4.2多個(gè)二進(jìn)制數(shù)排序7.4.3最大值多種進(jìn)制7.4.4 十進(jìn)制轉(zhuǎn)換為r進(jìn)制7.4.1 統(tǒng)計(jì)單詞個(gè)數(shù)解法解法1: 如果一個(gè)空格后跟一個(gè)非空格
38、,一定是新單詞開始: for(i=0; stri!=0; i+) 若stri是空格,stri+1不是空格,則新單詞出現(xiàn), count+ 問:第一個(gè)單詞沒算上? 答: count再加1即可!? 再問:若第一個(gè)單詞前有空格會(huì)怎樣?就又多了1 答:在str0不是空格的情況下count增1;解決問題:解決問題: 從鍵盤讀入一個(gè)字符串,統(tǒng)計(jì)其中的單詞個(gè)數(shù)。程序?qū)崿F(xiàn)#includeint main() char str1000; int i, word, count; count = 0; gets(str); for(i = 0; stri != 0; i+) if(stri = & stri+
39、1 != ) /一個(gè)單詞開始 count+; if(str0 != ) /若第一個(gè)字符不是空格 count+; printf(%dn,count); 解法2:如果一個(gè)非空格后是一個(gè)空格,一定是單詞的結(jié)束: for(i=0; stri!=0; i+) 若stri不是空格,stri+1是空格,則新單詞出現(xiàn),count+問:最后一個(gè)單詞沒算上?答: count在加1即可???再問:若最后一個(gè)單詞后有空格會(huì)怎樣?就又多了1答:在strlen-1不是空格的情況下count增1; 程序?qū)崿F(xiàn)#includeint main() char str1000; int i, count, len; count =
40、0; gets(str); for(i = 0; stri != 0; i+) if(stri != & stri+1 = ) /一個(gè)單詞結(jié)束 count+; len = strlen(str); if(strlen-1 != ) /若最后一個(gè)字符不是空格 count+; printf(%dn,count); 解法3:設(shè)置一個(gè)標(biāo)志變量word開始word置0for(i=0; stri!=0; i+) /掃描整個(gè)字符串 若stri是空格 word置0 若stri不是空格且word=0 則新單詞出現(xiàn),count+; word置1; 程序?qū)崿F(xiàn)#includeint main() char s
41、tr1000; int i, word, count; word = 0; count = 0; gets(str); for(i = 0; stri != 0; i+) if(stri = ) word = 0; if(stri != & word = 0) /新單詞出現(xiàn) count+; word = 1; printf(%dn,count); 課堂練習(xí)輸入若干行字符,統(tǒng)計(jì)其字符數(shù)、行數(shù)和空白符(空格、回車、制表符)的個(gè)數(shù)欣賞大師的代碼最后看一個(gè)例子,欣賞一下大師如何恰當(dāng)?shù)厥褂脴?biāo)志變量。下面的代碼出自K&R,功能是統(tǒng)計(jì)輸入的行數(shù)、單詞數(shù)和字符數(shù)。單詞之間的分隔符是空格、回車或
42、制表符。 #define IN 1 /*在單詞內(nèi)*/#define OUT 0 /*在單詞外*/* 統(tǒng)計(jì)輸入的行數(shù)、單詞數(shù)和字符數(shù) */main() int c, nl, nw, nc, state; state = OUT; nl = nw = nc = 0; while(c = getchar() != EOF) +nc; if( c = n) +nl; if( c = | c = n | c = t) state = OUT; else if(state = OUT) state = IN; +nw; printf(%d %d %dn, nl , nw , nc ); 要限制標(biāo)志變量的使
43、用。在代碼中輕率地使用flag之類的標(biāo)志變量會(huì)使代碼晦澀難度難以維護(hù),從而變成垃圾代碼。但這里,標(biāo)志變量恰當(dāng)?shù)厥褂昧藄tate這個(gè)與問題相貼切的名字。再加上兩個(gè)漂亮的符號(hào)常量IN和OUT,使得代碼的含義不言自明,連注釋都用不著。 7.4.2 多個(gè)二進(jìn)制數(shù)排序解決問題:解決問題:輸入三個(gè)二進(jìn)制數(shù),要求將這三個(gè)二進(jìn)制數(shù)對(duì)應(yīng)的十進(jìn)制整數(shù)按從小到大的順序輸出。 思路分析:思路分析: 1)二進(jìn)制數(shù)要用字符串來存儲(chǔ),比如一個(gè)9位的十進(jìn)制數(shù)對(duì)應(yīng)的二進(jìn)制數(shù)長度是30位左右,如果用%d來獲取就會(huì)產(chǎn)生類型溢出。2)調(diào)用函數(shù)BToD()將一個(gè)二進(jìn)制數(shù)轉(zhuǎn)化為十進(jìn)制整數(shù)。 3)讀入三個(gè)字符串s1,s2,s3分別調(diào)用三次
44、BToD函數(shù)得到對(duì)應(yīng)的三個(gè)十進(jìn)制數(shù),對(duì)這三個(gè)十進(jìn)制數(shù)排序輸出。 BToD()函數(shù)的實(shí)現(xiàn)/*函數(shù)的功能是計(jì)算k進(jìn)制的字符串str對(duì)應(yīng)的十進(jìn)制數(shù)*/int BToD(char str, int k);假設(shè)str: ”3456”,進(jìn)制為10,將十進(jìn)制的”3456”轉(zhuǎn)換為十進(jìn)制整數(shù)3456/d將不斷左移(乘10),再加上個(gè)位d=0; 掃描字符串”3456”:i=0: d=d*10+3=3;i=1:d=3*10+4=34;i=2:d=34*10+5=345;i=3: d=345*10+6=3456假設(shè)str: ”1101”,進(jìn)制為2,將二進(jìn)制的”1101”轉(zhuǎn)換為十進(jìn)制整數(shù)/d將不斷左移(乘2),再加上個(gè)
45、位d=0;掃描字符串”1101”:i=0: d=d*2+1=1;i=1:d=1*2+1=3;i=2:d=3*2+0=6;i=3: d=6*2+1=13程序7-6的main()int main(void)char str1N, str2N, str3N;int a, b, c, temp;scanf(%s%s%s, str1, str2, str3); /* 輸入三個(gè)二進(jìn)制數(shù) */a = BToD(str1); /* 函數(shù)調(diào)用三次,得到三個(gè)十進(jìn)制數(shù) */b = BToD(str2);c = BToD(str3); if(a b) temp = a; a = b; b = temp; if(a c
46、) temp = a; a = c; c = temp; if(b c) temp = b; b = c; c = temp; printf(%d %d %dn, a, b, c);return 0;程序7-6的BToD()/* 把一個(gè)二進(jìn)制數(shù)轉(zhuǎn)換成對(duì)應(yīng)的十進(jìn)制數(shù) */int BToD(char str) int i, d; d = 0; for(i = 0; stri != 0 ; i+) d = d * 2 + (stri - 0); return d;7.4.3 最大值多種進(jìn)制解決問題:解決問題:輸入n個(gè)非負(fù)整數(shù),每個(gè)數(shù)的進(jìn)制由其后面的數(shù)字k指定,k=2且k max, 更新max 輸出m
47、ax;scanf(%s%d, a, &k);d = KToD(a, k);int KToD(char str, int k); int main(void) int i, n, k, d, max; char a50; scanf(%d, &n); max = 0; /*所有輸入為非負(fù)數(shù)*/ for(i=1; i max) max = d; printf(%dn, max); return 0; 程序7-7的KToD()/*將k進(jìn)制數(shù)str轉(zhuǎn)換為十進(jìn)制*/int KToD(char str, int k) int i, sum; sum = 0; for(i = 0; stri
48、 != 0; i+) sum = sum * k + (stri - 0); return sum; 課堂練習(xí) 改寫B(tài)ToD函數(shù),將k(k = 16)進(jìn)制轉(zhuǎn)換為10進(jìn)制。7.4.4 十進(jìn)制轉(zhuǎn)換為r進(jìn)制問題1:將一個(gè)十進(jìn)制n(0n109)轉(zhuǎn)換為16進(jìn)制數(shù)輸出。問題2:將一個(gè)十進(jìn)制n(0n109)轉(zhuǎn)換為二進(jìn)制數(shù)存入字符串str。問題3:將一個(gè)十進(jìn)制n(0n109)轉(zhuǎn)換為r(1r17)進(jìn)制數(shù)存入字符串str。問題1的求解分析:分析:以十進(jìn)制格式讀入n,再以十六進(jìn)制格式輸出n#includeint main() int n; scanf(%d, &n); printf(%x , n); ret
49、urn 0;實(shí)現(xiàn):實(shí)現(xiàn):問題2的求解問題1的方法只適合于八進(jìn)制和十六進(jìn)制。下面討論十進(jìn)制向二進(jìn)制的轉(zhuǎn)換分析:除2取余法13262321201110高低10110難點(diǎn):先得到的余數(shù)位權(quán)最低。實(shí)現(xiàn)方法 (1)將得到的余數(shù)依次放入數(shù)組str0、str1.,記下長度len。(2)加上字符串結(jié)束標(biāo)志0(3)將字符串str逆置11010問題3的求解將十進(jìn)制整數(shù)n轉(zhuǎn)化為r(1r17)進(jìn)制注意:由于itoa函數(shù)不是標(biāo)準(zhǔn)C語言函數(shù),所以不能在所有的編譯器中使用。這時(shí)需要自定義函數(shù)itoa。其實(shí)stdlib.h中的itoa函數(shù)可以將十進(jìn)制轉(zhuǎn)換為r進(jìn)制:char *itoa(int value, char *str
50、ing, int r)將int整型數(shù)轉(zhuǎn)化為radix進(jìn)制一個(gè)字符串,并將值保存在數(shù)組string中, r的范圍為2-36 #include#includeint main() int n, r; char str30; scanf(%d%d, &n, &r); itoa(n, str, r); puts(str); return 0;進(jìn)制轉(zhuǎn)換函數(shù)的實(shí)現(xiàn)要求自定義函數(shù) DToR(int n, char str, int r),將十進(jìn)制整數(shù)n轉(zhuǎn)化為r(1r17)進(jìn)制,存入str。DToR的實(shí)現(xiàn):除r取余法100016621631614830高低難點(diǎn):若r大于9,需要將數(shù)字10轉(zhuǎn)換為
51、a,11轉(zhuǎn)換為b.3E80如果余數(shù) d 10 strk = d + 0; 否則 strk = d 10 + A;void dToR(int n, char str, int r) int k = 0, d; char H=0123456789ABCDEF; while(n != 0) d = n % r; strk = Hd; k+; n = n/r; strk = 0; strrev(str);void dToR(int n, char str, int r) int k, d; k = 0; while(n != 0) d = n % r; if(d 10) strk = d + 0; e
52、lse strk = d 10 + A; k+; n = n / r; strk = 0; strrev(str);善用數(shù)組簡化計(jì)算! 課堂練習(xí): 多少個(gè)圈( 1668)n給你一個(gè)整數(shù),他到底有幾個(gè)圈圈呢?比如數(shù)字“0,9,6” 都是有一個(gè)圈圈, “8” 有兩個(gè)圈圈, 其他數(shù)字沒有圈圈。nInput 一個(gè)整數(shù)n(1= n 0) count += zero n % 10; n /= 10; printf(%dn, count); return 0;n個(gè)字符串的最大值n輸入n和n 個(gè)字符串,用二維數(shù)組保存所有字符串,并輸出最大字符串。(1) 讀入 n(2) for(i=0;in;i+) 讀入一個(gè)字
53、符串,存入stri: gets(stri);(3) max置為空串(最小字符串):max = “”;(3) for(i = 0; i n; i+) 若stri大于max,則更新max(4) 輸出字符串max 7.5 字符串?dāng)?shù)組 一維字符數(shù)組可以存儲(chǔ)一個(gè)字符串,二維字符數(shù)組可以存儲(chǔ)一維字符數(shù)組可以存儲(chǔ)一個(gè)字符串,二維字符數(shù)組可以存儲(chǔ)多個(gè)字符串,稱為字符串?dāng)?shù)組。多個(gè)字符串,稱為字符串?dāng)?shù)組。 字符串?dāng)?shù)組的每一行元素中都含有字符串結(jié)束符字符串?dāng)?shù)組的每一行元素中都含有字符串結(jié)束符0,因此,因此它的一行元素可以和字符串一樣輸入、輸出及初始化。它的一行元素可以和字符串一樣輸入、輸出及初始化。如:如:char
54、 color 10=red, blue, yellow, green, purple;字符串?dāng)?shù)組可以用二維字符數(shù)組存儲(chǔ)。字符串?dāng)?shù)組可以用二維字符數(shù)組存儲(chǔ)。color0color數(shù)組,有5個(gè)元素,每個(gè)是一個(gè)一維數(shù)組,可以存儲(chǔ)一個(gè)字符串color1color2color3color4n個(gè)字符串的最大值n輸入n和n 個(gè)字符串,用二維數(shù)組保存所有字符串,并輸出最大字符串。(1) 讀入 n(2) for(i=0;in;i+) 讀入一個(gè)字符串,存入stri: gets(stri);(3) max置為空串(最小字符串):max = “”;(3) for(i = 0; i n; i+) 若stri大于max,
55、則更新max(4) 輸出字符串max 程序7-9:最大字符串 char maxStrLEN = ; scanf(%d, &n); getchar(); /*處理回車,以免被后面的gets() 作為空字符串讀入*/ for(i = 0; i 0) /*若stri比maxStr大則替換maxStr*/ strcpy(maxStr, stri); printf(result is:); puts(maxStr); return 0;n個(gè)字符串排序n解決問題:輸入n和n 個(gè)字符串,將n個(gè)字符串按字典序排序輸出。每個(gè)字符串長度不大于80。實(shí)現(xiàn)過程:(1) 讀入 n(2) for(i=0; in;
56、 i+) 讀入一個(gè)字符串,存入stri: gets(stri);(3)排序(4) for(i=0; in; i+) puts(stri); /*字符串?dāng)?shù)組排序*/for(i=1;in;i+) for(j=0;jn-i;j+) if(strj大于strj+1) strj與strj+1互換 /*字符串?dāng)?shù)組排序*/for(i=1; in; i+) for(j=0; j 0) strcpy(temp, strj); strcpy(strj, strj+1); strcpy(strj+1, temp); 課堂練習(xí):判斷字符矩陣是否相等n讀入兩個(gè)m行n列的字符矩陣,只含有#和*,表示兩個(gè)迷宮地圖。 #表示
57、紅色方磚,* 表示黑色方磚。請(qǐng)判斷兩個(gè)迷宮是否完全相同。n輸入m和n,表示迷宮尺寸 然后是兩個(gè)m行n列的字符矩陣,#表示紅色方磚,* 表示黑色方磚。n若兩個(gè)矩陣完全相同,輸出”yes”,否則輸出”no” 善于整體處理字符串input(char mapNN, int m) /輸入迷宮 for(int i = 0; i m; i+) scanf(“%s”, mapi ); /* 判斷兩個(gè)矩陣是否完全相同 */MapCmp(char s1NN,char s2NN, int m) for(int i = 0; i m; i+) if( strcmp(s1i, s2i) != 0) return 0; return 1; 善用函數(shù)思維 1157 連續(xù)n個(gè)1n計(jì)算機(jī)數(shù)據(jù)都是由0和1組成的,看著長長的0101001110101111011,要找出連續(xù)n個(gè)1的子串有多少個(gè),確實(shí)麻煩,請(qǐng)你編程實(shí)現(xiàn)吧。n輸入第一行為一個(gè)字符串,由0和1組成,長度小于1000;輸入第二行為一個(gè)正整數(shù)n。n輸出一個(gè)整數(shù),表示連續(xù)n個(gè)的1的子串的個(gè)數(shù)。n樣例輸入 0101001110101111011 2n樣例輸出 6解題思路n搜索所有長度為n的子字符串,統(tǒng)計(jì)全為1的子串個(gè)數(shù)len = strlen(str)for(i = 0; i = len - n; i+) /若從stri開始的n個(gè)字符串全1 if(check(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年復(fù)合材料原材料采購與物流解決方案合同3篇
- 2025搬家合同協(xié)議模板:搬家服務(wù)與家具組裝驗(yàn)收合同3篇
- 2024深圳建筑抗震加固工程合同范本
- 二零二五年度企業(yè)資源管理平臺(tái)續(xù)約協(xié)議
- 2025年度二手房交易合同正副本3篇
- 2025年度演藝經(jīng)紀(jì)合同藝人經(jīng)紀(jì)事務(wù)及分成3篇
- 2024幼兒園員工勞動(dòng)合同簽訂與備案操作指南3篇
- 2024年06月福建中國工商銀行福建分行社會(huì)招考筆試歷年參考題庫附帶答案詳解
- 2025年度木材產(chǎn)業(yè)生態(tài)保護(hù)與可持續(xù)發(fā)展合同模板
- 2024模板研發(fā)與場(chǎng)地租賃一體化服務(wù)合同范文3篇
- 2024年寧波永耀供電服務(wù)有限公司招聘筆試參考題庫附帶答案詳解
- 山西師范大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)基礎(chǔ)期末沖刺卷及答案
- 工程圖學(xué)(吉林聯(lián)盟)智慧樹知到期末考試答案2024年
- 天津市部分區(qū)2022-2023學(xué)年七年級(jí)上學(xué)期期末語文試題(含答案)
- 壓縮空氣氣體管道吹掃試壓專項(xiàng)方案
- 2021年海南省公務(wù)員考試《行測(cè)》真題和答案解析
- 餐廳創(chuàng)新改革方案課件
- 《社會(huì)歷史的決定性基礎(chǔ)》共171張高中語文選擇性必修中冊(cè)
- 鐵嶺衛(wèi)生職業(yè)學(xué)院招聘考試題庫2024
- 鐵路信號(hào)基礎(chǔ)信號(hào)機(jī)課件
- 廣東省珠海市斗門區(qū)2023-2024學(xué)年七年級(jí)上學(xué)期期末英語試卷+
評(píng)論
0/150
提交評(píng)論