第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串 8-5 指標的應用 - 字串處理 8-6 標準函式庫的字串函數
8-1 C語言的字元檢查函數-1
8-1 C語言的字元檢查函數-2 在<ctype.h>標頭檔提供2個函數可以轉換英文字母的大小寫,如下表所示:
8-2 C語言的字串 8-2-1 字串的基礎 8-2-2 字串的初值與指定敘述
8-2-1 字串的基礎-說明 C語言的「字串」(String)是一維的字元陣列,也就是由字元資料型態組成的陣列結構。例如:宣告一個字元陣列來儲存字串,其宣告的方式,如下所示: char string[80]; 程式碼宣告長度為80的字元陣列,陣列名稱是string,陣列索引是從0開始,換言之,存取陣列元素是使用string[0]、string[1]~string[79]來存取,如下所示: char c; string[i] = c;
8-2-1 字串的基礎-結束字元 在字元陣列的結束需要加上'\0'字元當作結束字元,如下所示: string[LEN] = '\0'; 上述擁有結束字元的字元陣列是一個字串,其長度是從0到結束字元前為止的字元數,即LEN。
8-2-2 字串的初值與指定敘述-字串的初值1 字串的初值相當於指定C語言字元陣列的初值。例如:宣告擁有15個元素的字元陣列,如下所示: char str[15] = "hello! world\n"; 字元陣列是使用「“」雙引號的字串常數來指定陣列初值,此時字元陣列str[]的圖例,如下圖所示:
8-2-2 字串的初值與指定敘述-字串的初值2 使用陣列初值,如下所示 char str[15] = {'h','e','l','l','o','!',' ','w','o','r','l','d','\n','\0'}; 使用指定敘述指定字元陣列的元素值,如下所示: char str[15]; str[0] = 'h'; str[1] = 'e'; str[2] = 'l'; str[3] = 'l'; str[4] = 'o'; str[5] = '!'; str[6] = ' '; str[7] = 'w'; str[8] = 'o'; str[9] = 'r'; str[10] = 'l'; str[11] = 'd'; str[12] = '\n'; str[13] = '\0';
8-2-2 字串的初值與指定敘述-字串的指定敘述 C語言的字串是一種字元陣列,並不能使用指定敘述將字串指定給其它字元陣列。 如果在程式碼需要更改字串內容,例如:指定字串常數或將其它字串指定給str1,需要使用C語言標準函式庫<string.h>標頭檔的strcpy()函數,如下所示: strcpy(str1, “hello\n”); strcpy(str1, str);
8-3 字串的輸入與輸出 8-3-1 讀取與輸出字串 8-3-2 使用scanf()函數讀取字串 8-3-3 使用getchar()讀取整個字串
8-3-1 讀取與輸出字串-讀取 在C程式可以使用gets()函數從標準輸入裝置讀取整行文字內容的字串,函數是使用緩衝區讀取資料,所以需要等到使用者按下Enter鍵後,才會將字串送給C程式處理,如下所示: char line[80]; gets(line); 程式碼宣告字元陣列line[],大小是80個字元,然後以字元陣列為參數讀取字串內容,傳回值是字元陣列的指標,也就是字串內容。
8-3-1 讀取與輸出字串-輸出 在輸入字串後,C程式可以使用puts()函數將字串輸出到螢幕顯示,如下所示: puts(line); 上述程式碼可以將參數的字元陣列line[]輸出到螢幕顯示,並且在字串後自動加上新行字元。
8-3-2 使用scanf()函數讀取字串 在C程式除了使用gets()函數取得使用者輸入的字串外,我們也可以使用scanf()函數讀取使用者輸入的字串,如下所示: scanf("%s", line); 上述程式碼的函數參數一共有2個,第1個是格式字串,內含%s表示輸入的資料格式是字串,第2個參數是儲存讀取字串的變數,line是一個字元陣列,因為C語言的陣列名稱本身是位址,所以不需要「&」取址運算子。
8-3-3 使用getchar()讀取整個字串 我們可以使用for迴圈配合getchar()函數來摸擬gets()函數的功能,如下所示: for ( i = 0; (c=getchar()) !=EOF && c != '\n'; i++) line[i] = c; line[i] = '\0'; 程式碼for迴圈的第2部分先呼叫getchar()函數讀取一個字元(c=getchar()),然後檢查輸入字元是否為EOF或Enter鍵,在命令列提示字元按下Ctrl-Z組合鍵是EOF,如果不是,就將字元存入陣列中,最後在字元陣列的最後加上'\0'的字串結束字元。
8-4 指標與字串 8-4-1 指標與字串 8-4-2 字串的指標陣列 8-4-3 main主程式的命令列參數字串 8-4-4 函數傳回字串指標
8-4-1 指標與字串-說明 字串指標是char資料型態的指標,可以用來指向字元陣列或字串常數。首先宣告一維字元陣列的字串,如下所示: char str[16] = "This is a book."; 上述字元陣列是一個字串且指定初值,接著可以宣告指標變數指向此字串,如下所示: char *ptr = str; 上述程式碼宣告char資料型態的指標變數ptr,指向陣列名稱str,也就是字串第1個字元的位址,如下圖所示:
8-4-1 指標與字串-指向字串常數 當然,指標變數也可以用來指向字串常數,如下所示: char *ptr1; ptr1 = "This is an apple."; 程式碼宣告指標變數ptr1指向字串常數,當然指標變數可以隨時更改指向的字串。 例如:str1是另一個字元陣列的字串,我們可以將指標變數ptr1改為指向str1字串,如下所示: ptr1 = str1;
8-4-1 指標與字串-複製字串 例如:將字串str的內容複製到字串str1,指標變數ptr是指向str,ptr1是指向str1,複製字元的while迴圈,如下所示: while ( *ptr != '\0' ) { *(ptr1+i) = *ptr++; i++; } *(ptr1+i) = '\0';
8-4-2 字串的指標陣列-指標陣列 C語言的指標陣列最常用來建立字串的指標陣列,如下所示: #define ROWS 4 char *name2[ROWS] = {"陳會安", "江小魚", "楊過", "小龍女"};
8-4-2 字串的指標陣列-二維陣列 同樣的,我們也可以宣告二維陣列name1[][]儲存上述4個字串,如下所示: #define ROWS 4 #define COLUMNS 10 char name1[ROWS][COLUMNS] = {"陳會安", "江小魚", "楊過", "小龍女"};
8-4-2 字串的指標陣列-交換字串 當程式使用指標陣列儲存字串時,不只比較節省記憶空間,而且因為是指標,如果指標陣列的元素需要交換字串,只需更改指標指向的字串即可,如下圖所示:
8-4-3 main主程式的命令列參數字串-說明 C程式執行的進入點是main()主程式,換句話說,C應用程式是從程式檔案的main()主程式開始執行,main()主程式本身是一個函數,擁有整數和字串指標陣列共2個參數,如下所示: int main(int argc, char *argv[]) { …… } main()主程式擁有2個參數,第1個參數argc是命令列參數的個數,第2個參數char *argv[]是指標陣列,每一個陣列元素指向一個字串。
8-4-3 main主程式的命令列參數字串-傳入命令列參數 在Windows XP/2000的「命令提示字元」視窗可以在命令列執行程式時,傳遞執行時的命令列參數,如下所示: C:\C++\Ch8>Ch8_4_3.exe 1 2 3 4 Hello Enter 上述命令列輸入1、2、3、4和Hello共5個參數,以空白字元分隔,main()主程式取得的第1個參數值是6,因為命令列輸入的程式執行檔本身也算1個參數,所以為5+1=6。
8-4-3 main主程式的命令列參數字串-取得命令列參數 第2個參數可以使用argv[0]、argv[1]、argv[2]、argv[3]、argv[4]和args[5]陣列元素依序取得參數字串,如下所示: argv[0] = "Ch8_4_3.exe" argv[1] = "1" argv[2] = "2" argv[3] = "3" argv[4] = "4" argv[5] = "Hello"
8-4-4 函數傳回字串指標 C語言的函數傳回值也可以是字串指標,不過因為指標是指向其它變數的位址,換句話說,傳回值不可以是函數程式區塊中宣告的自動變數,只能是函數的傳址參數或是static靜態變數,如下所示: char *strcopy(char *, char *); char *monthName(int); 上述2個函數原型宣告都是傳回字元型態的指標變數,第1個函數傳回傳址方法傳遞的參數,第2個傳回static靜態變數。
8-5 指標的應用 - 字串處理 8-5-1 取得字串長度 8-5-2 字串連結 8-5-3 字串比較
8-5-1 取得字串長度 字串是一個字元陣列,我們可以使用指標遞增運算計算字串長度,如下所示: char *ptr = str; while ( *ptr != '\0' ) ptr++; return ptr - str; 程式碼使用while迴圈走訪到字串的最後1個字元,然後使用ptr-str指標減法運算取得字串長度。
8-5-2 字串連結-說明 字串的連結是將兩個字串結合成一個字串。例如:兩個字串的結合範例,如下圖所示:
8-5-2 字串連結-實作 連結函數的實作是結合字串複製和字串長度計算,首先使用字串長度的while迴圈,如下所示: while ( *ptr++ != '\0' ); ptr--; 程式碼使用while迴圈走訪到字串的最後1個的結束字元,ptr--指向結束字元的前一個字元,然後使用另一個while迴圈複製字串,如下所示: while ( (*ptr++=*source++) != '\0' );
8-5-3 字串比較-比較迴圈 字串的比較是比較2個字串的內容,如果2個字串完全相同的話,就傳回0。如果不相同,使用ASCII的字元碼比較不同的哪一個字元。 字串比較函數使用for迴圈從頭比較2個字串中的每一個字元,直到字元不相等或字串結束字元,如下所示: for ( ; *source == *target; source++, target++) if ( *source == '\0') return 0;
8-5-3 字串比較-比較不相等的字元 如果不相等,接著就使用if條件比較最後不相等的2個字元,以決定字串大小,如下所示: if ( (*source-*target) < 0 ) return -1; else return 1; 上述if條件比較最後2個字元,*source>*target傳回1,*source<*target傳回-1。
8-6 標準函式庫的字串函數 8-6-1 字串轉換函數 8-6-2 字串處理
8-6-1 字串轉換函數 在<stdlib.h>標頭檔定義一些數值轉換的工具函數,函數的說明如下表所示:
8-6-2 字串處理