Transcript C/C++

第8章 字元與字串處理





8-1
8-2
8-3
8-4
8-5
C語言的字元檢查函數
指定字串的初值
指標與字串
字串處理
C語言的字串函數
8-1 C語言的字元檢查函數-1
函數
說明
isalnum(int)
如果是英 文字母 isalpha(int)或十進位 數字 isdigit(int)為 true
真,傳回非零值,否則為 0
isalpha(int)
如果是英文字母,不論是 isupper(int)大寫或 islower(int)小寫為
true 真,傳回非零值,否則為 0
iscntrl(int)
如果是控制字元,傳回非零值,否則為 0
isdigit(int)
如果是十進位的數字字元,即 0~9,傳回非零值,否則為 0
isxdigit(int)
如果是十六進位的數字字元,即 0~9、A~F 和 a~f,傳回非零
值,否則為 0
8-1 C語言的字元檢查函數-2
isprint(int)
如果是包含空白字元的可顯示字元,傳回非零值,否則為 0
isgraph(int)
如果是空白字元之外的可顯示字元,傳回非零值,否則為 0
isspace(int)
如果是空白字元,傳回非零值,否則為 0
ispunct(int)
如果是標點符號字元,傳回非零值,否則為 0
islower(int)
如果是小寫英文字母的字元,傳回非零值,否則為 0
isupper(int)
如果是大寫英文字母的字元,傳回非零值,否則為 0
函數
說明
int tolower(int) 如果參數是英文大寫字母,傳回小寫字母,否則傳回參數值
int toupper(int) 如果參數是英文小寫字母,傳回大寫字母,否則傳回參數值
8-2 指定字串的初值-說明

C語言並沒有字串資料型態,字串是一種字
元型態的陣列,只是使用’\0’字串結束
字元標示字串的結束。在其它程式語言,
例如:BASIC、FORTAN和Java語言都擁
有專屬的字串資料型態。
8-2 指定字串的初值-字串的初值
1

字串的初值相當於指定C語言字元陣列的初值。
例如:宣告擁有15個元素的字元陣列,如下:
char str[15] = "hello, world\n";

程式碼是一個字元陣列,使用「"」雙引號的字串
常數指定陣列初值,此時字元陣列的圖例,如下
圖所示:
8-2 指定字串的初值-字串的初值
2

還有另外2種方法:第2種是使用陣列初值,如下
所示
char str[15] = {'h','e','l','l','o',',','
','w','o','r','l','d','\n','\0'};

第3種方法是使用指定敘述指定字元陣列各元素的
值,如下所示:
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 指定字串的初值-指定敘述

C語言的字串是字元陣列,並不能使用指定敘述
將字串指定給其它的字元陣列。例如:宣告字元
陣列str1,其大小也是15,如下所示:
char str1[15];


字串只能在宣告時使用字串常數指定字串內容。
如果需要指定字串常數或將其它字串指定給str1,
使用的是標準函式庫<string.h>標頭檔的
strcpy()函數,如下所示:
strcpy(str1, "hello\n");
strcpy(str1, str);
8-3 指標與字串




8-3-1
8-3-2
8-3-3
8-3-4
指標與字串
字串的指標陣列
main主程式的命令列參數字串
函數傳回字串指標
8-3-1 指標與字串-說明

字串指標是一個char資料型態的指標,可以用來
指向字元陣列或字串常數。首先宣告字元陣列的
字串,如下所示:
char str[15] = "This is a book.";

接著宣告指標變數指向此字串,如下所示:
char *ptr = str;
8-3-1 指標與字串-指向字串常數

指標變數也可以用來指向字串常數,如下
所示:
char *ptr1;
ptr1 = "This is a pen.";

程式碼宣告指標變數ptr1指向字串常數,
當然指標變數可以隨時改成指向其它字串,
例如:str1是一個字元陣列的字串,如下
所示:
ptr1 = str1;
8-3-1 指標與字串-複製字串

將字串str的內容複製到字串str1,指標變數ptr是
指向str,ptr1是指向str1,複製的迴圈,如下:
while ( *ptr != '\0' )
{
*(ptr1+i) = *ptr++;
i++;
}
*(ptr1+i) = '\0';

while迴圈的條件是檢查是否到了str字串的結束
字元,ptr1和ptr指標變數分別使用加法和遞增運
算移到下一個字元,最後在ptr1加上結束字元'\0',
就可以將字串str複製到str1。
8-3-2 字串的指標陣列-說明

C語言的指標陣列最常應用在字串的指標陣
列,如下所示:
#define ROWS
4
char *name[ROWS] = {"陳會安", "江小魚",
"張無忌", "楊過"};

上述程式碼宣告字串的指標陣列name且指
定初值。
8-3-2 字串的指標陣列-圖例
8-3-2 字串的指標陣列-交換字串
8-3-2 字串的指標陣列-顯示指標
陣列

在指標陣列取得每一個元素的字串,只需
使用指標變數指向各元素,如下所示:
ptr = name[i];

程式碼可以取得指定元素的字串指標,然
後使用指標運算顯示字串內容,如下:
for ( j = 0; *(ptr+j) != '\0'; j++)
printf("%c", *(ptr+j));
printf("]\n");
8-3-3 main主程式的命令列參數
字串-說明

C程式執行的進入點是main()主程式,換句話說,
程式是從程式檔案的main()主程式開始執行,
main()主程式擁有2個參數分別是整數和字串的
指標陣列,如下所示:
main(int argc, char *argv[])
{ …… }

main()主程式擁有2個參數,第1個參數是命令列
參數的個數,第2個參數char *argv[]是指標陣
列,每一個陣列元素指向一個字串。
8-3-3 main主程式的命令列參數
字串-傳遞參數

在「命令提示字元」視窗可以使用主程式
的參數傳遞執行時的命令列參數,如下所
示:
D:\C++\Ch08>Ch8-3-3.exe 1 2 3 4 Test Enter

命令列輸入1、2、3、4和Test共5個參數,
以空白字元分隔,main()主程式取得的第
1個參數值是6,因為命令列輸入的程式執
行檔Ch8-3-3.exe本身也算1個參數,所以
為5+1=6。
8-3-3 main主程式的命令列參數
字串-取得參數值

第2個參數使用argv[0]、argv[1]、
argv[2]、argv[3]、argv[4]和args[5]
陣列元素依序取得參數字串,如下所示:
argv[0]
argv[1]
argv[2]
argv[3]
argv[4]
argv[5]
=
=
=
=
=
=
"Ch8-3-3.exe"
"1"
"2"
"3"
"4"
"Test"
8-3-4 函數傳回字串指標

C語言的函數傳回值也可以是字串指標,不
過因為指標是指向其它變數的位址,傳回
值不可以是在函數程式區塊中宣告的自動
變數,只可以是函數的傳址參數或是static
靜態變數,如下所示:
char *strcopy(char *, char *);
char *monthname(int);

函數原型宣告都是傳回字元型態的指標變數,第1
個是傳回傳址的參數,第2個傳回static靜態變數。
8-4 字串處理





8-4-1
8-4-2
8-4-3
8-4-4
8-4-5
取得字串長度
字串複製
字串連結
字串比較
子字串的搜尋
8-4-1 取得字串長度

字串是一個字元陣列,計算字串長度的方法就是
一維陣列走訪和指標的遞增運算,如下所示:
for ( i = 0; str[i]!='\0'; i++ );

for迴圈會執行到陣列元素為'\0'為止,此時變數
i就是字串長度。指標版本是使用指標遞增運算,
如下所示:
char *ptr = str;
while ( *ptr != '\0' )
ptr++;
return ptr - str;
8-4-2 字串複製

字串複製是將字串內容複製到其它的字元陣列,
其目的是為了保留原始字串,以避免執行其它字
串處理時,更改到原始字串的內容。
char *ptr = dest;
while ( (*ptr++=*source++) != '\0' );
return dest;

陣列版本的字串複製也是使用類似的while迴圈,
如下所示:
while ((dest[i]=source[i]) != '\0')
i++;
8-4-3 字串連結-說明

字串的連結是將兩個字串結合成一個字串。例如:
兩個字串的結合範例,如下所示:
8-4-3 字串連結-陣列版函數

陣列版本的實作是字串複製和字串長度函數的結
合,只需使用字串長度的迴圈找到字串結束字元
的索引,如下所示:
for ( i = 0; dest[i] != '\0'; i++);

接著就可以開始複製字串,如下所示:
while ( source[j] != '\0' )
{
dest[i+j] = source[j];
j++;
}
8-4-3 字串連結-指標版函數

指標版本也一樣是字串長度和複製函數結合,如
下所示:
while ( *ptr++ != '\0' );

程式碼使用while迴圈走訪到字串的最後一個的結
束字元,然後就使用迴圈複製字串,如下所示:
while ( (*ptr++=*source++) != '\0' );
8-4-4 字串比較-說明

字串的比較是比較兩個字串的內容,如果
兩個字串完全相同的話,就傳回0。如果不
相同,使用ASCII的字元碼比較不同的那一
個字元。
8-4-4 字串比較-函數

字串比較函數是使用迴圈從頭開始比較兩個字
串中的每一個字元,直到字元不相等或字串結
束字元,如下所示:
for ( i = 0; source[i] == target[i]; i++)
if ( source[i] == '\0')
return 0;

如果不相等,接著就比較最後不相等的兩個字
元,以決定字串的大小,如下所示:
if ((source[i]-target[i]) < 0 )
return -1;
else
return 1;
8-4-5 子字串的搜尋-說明

子字串的搜尋是指在原始字串中找尋某特
定字串是否存在,如果存在,這個特定字
串就是原始字串的子字串。
8-4-5 子字串的搜尋-函數

字串搜尋是字串比較的延伸,因為原始字串的任
何一個字元都可能是特定字串的開始,函數需要
使用二層的巢狀迴圈執行字串比較,如下所示:
for ( i = 0; source[i] != '\0'; i++ ) {
for (j = i, k = 0; target[k] != '\0' &&
source[j] == target[k]; j++, k++ );
if ( k > 0 && target[k] == '\0')
return i;
}
return -1;
8-5 C語言的字串函數

8-5-1 字串轉換函數

8-5-2 字串處理
8-5-1 字串轉換函數
函數
說明
double atof(char *) 將參數的字串轉換成浮點數,如果字串不能轉換傳回 0.0
int atoi(char *)
將參數的字串轉換成整數,如果字串不能轉換傳回 0
float atol(char *)
將參數的字串轉換成長整數,如果字串不能轉換傳回 0
8-5-2 字串處理-1
函數
說明
size_t strlen(char *)
傳回參數字串的長度
char *strcpy(char *d, char *s)
將參數的字串 s 複製到字串 d,傳回字串
d 的指標
char *strncpy(char *d, char *s, size_t n) 將參數的字串 s 複製最多 n 個字元到字串
d,傳回字串 d 的指標,需要自行加上字
串結束字元’\0’
char *strcat(char *d, char *s)
將參數的字串 s 連結到字串 d 之後,傳回
字串 d 的指標
char *strncat(char *d, char *s, size_t n) 將參數的字串 s 連結最多 n 個字元到字串
d 之後,傳回字串 d 的指標
8-5-2 字串處理-2
int strcmp(char *d, char *s)
比較參數字串 s 與字串 d,d < s 傳回負
值,d = s 傳回 0,d > s 傳回正值
int strncmp(char *d, char *s, size_t n)
比較參數字串 s 與字串 d 的前 n 個字元,
d < s 傳回負值,d = s 傳回 0,d > s 傳回
正值
char *strchr(char *d, char c)
傳回指標指向在參數字串 d 中第 1 次出現
字元 c 的位置,如果沒有傳回 NULL
char *strrchr(char *d, char c)
傳回指標指向在參數字串 d 中最後 1 次出
現字元 c 的位置,沒有傳回 NULL
char *strstr(char *d, char *s)
傳回指標指向在參數字串 d 中第 1 次出現
字串 s 的位置,沒有傳回 NULL