C字串
C中的字串是以空字元('\0')結尾的一個char陣列,基本的實現字串的方法有:字串常量,字串陣列,char陣列,char指標。字串使用廣泛,如與使用者互動等處理自然語言的情況。C為其提供的許多函式主要包含在string.h(各種處理函式)和stdio.h(面向字串的輸入輸出函式)。
一、字串的實現
1.字串常量
字串常量(又稱字串文字),是指位於一對雙引號中的任何字元,編譯器會自動在其結尾新增'\0'作為結束標誌。字串常量屬於靜態儲存類,即使多次呼叫這個常量它在記憶體中也只儲存一份(當然,再用字串常量初始化char陣列時它被複制了,這時副本已經不是字串常量了)。字串常量做引數時形參通常宣告為const char *。
2.char陣列與char指標
(1)在使用char陣列時需要有足夠大的空間來儲存字串。在對char陣列進行初始化的情況下可以不指定長度而由編譯器決定(最小長度,字元數加一個'\0')。
(2)char陣列初始化有兩種方式,可以用一個字串常量,也可以像數值陣列一樣用花括號包含初始化表列,未被初始化的元素被自動置為'\0'【char [] = “example”;】。
(3)在使用初始化表列且未指定陣列長度時,一定要在結尾加上'\0',否則這只是一個字元陣列而非字串。和其它陣列一樣char陣列是一個指向一段連續空間首地址的指標常量。
(4)char指標指向一個字串的首地址(通常是字串常量也可以是一個char陣列)。對char陣列賦值必須逐個元素賦值,對char指標賦值只需要複製地址即可。
//例 char *ch;//宣告一個指標ch ch = (char *)malloc(sizeof(char));//ch指向一個char型別的陣列
(5)char指標可以進行加減,自增(減),取值運算也可以像陣列一樣進行變址運算(s[])。而char陣列不允許修改。陣列與指標在記憶體模型上有更多區別。比如:
char arr[M]; char *ptr = (char *)malloc(sizeof(char)); printf("%d %d\n", sizeof(arr),sizeof(ptr) );
(6)char指標指向的字串在記憶體中只儲存了一份,一旦修改所有引用處均被修改,而且char指標難以指定空間大小(必須用malloc)。
char指標初始化後,儘量不要修改其內容(包括用來接受輸入),或者使用const來保護其內容。因為char指標指向空間有限,一般只作為字串常量使用。
3.字串陣列
(1)批量處理字串可以使用字串陣列,可以使用二維char陣列(char s[][])或指標陣列(char*s[])。其異同與數值型二維陣列和指標陣列相同。
(2)由於二維陣列的第二維長度必須保證大於最長的字串,指標陣列每個字串只需要最小長度,所以指標陣列的儲存密度較高。同樣由於初始化困難,指標陣列通常作為常量使用。
二、字串操作函式
字串的輸入輸出請參見I/O一文。除特殊說明外,下列函式均需包含string.h。
1.字串長度:
size_t strlen(const char*);
返回字串第一個'\0'前的字元數(不包含'\0'),即字串的有效長度。
2.字串複製(string copy):
char* strcpy(char*dest,const char*sco);
將引數2(source)中字串複製到引數1(destination)中,返回指向引數1的指標。需要程式設計師保證串1足夠大。
char*strncpy(char*dest,const char sco,size_t n);
將前n個字元進行復制。
void*memcpy(void*dest,const void*sco,size_t size);
將sro指向的記憶體內容複製到dest,由size引數指定長度。需包含string.h或memory.h。memcpy可以複製任何內容,strcpy只能複製字串。
3.字串比較(string compare):
int strcmp(const char*,const char*);
比較字串相同返回0,不同返回第一個不同字元ASCII碼之差。大小寫不敏感,常與邏輯非(!)結合表示字串相同。
int stricmp(const char*,const char*);
以大小寫不敏感的方式複製字串。
4.字串連線(string catch):
char*strcat(char*dest,const char*src);
將src字串接在dest後面(自動移動'\0'),返回dest指標。需程式設計師保證dest足夠長。
char*strncat(char*dest,char*sco,size_t n);
將sco的前n個字元連線在dest上。
5.查詢子串(string string):
char*strstr(const char*text,const char*model);
在正文(test)中查詢模式子串(model),返回從指向第一個匹配點的char指標。可以使用
strlen(test)-strlen(strstr(test,model))來求得匹配點的下標。
6.查詢字元(string character):
char* strchr(char*test,char c);
在test中查詢字元c,返回指向c的指標,可以利用長度相減確定下標。也可以用來查詢字串中是否有給定字符集中的字元(或給定字符集中沒有的字元)。
for( int i = 0; i < strlen(test); i++) { if(strchr(lib,test[i])) { //… } }
在字符集(lib)中查詢test中的每一個字元,判斷test中的哪一個(或全部)字元是否在(或不在)字符集內。在test中查詢lib中的每一個字元通過返回值判斷test中有lib裡的哪個字元。
7.向字串格式化輸出(string print format):
int sprintf(char*buf,const char*format,…);
用法類似printf,但是向字串buf輸出並返回buf的長度(同strlen),多次向同一字串輸出將覆蓋原有內容。需包含stdio.h。
可以用來將數字逐位列印到陣列中,對每一位進行處理。但要注意字串中的是數字字元而不是數字,不要忘記-'0'【9=”9”-”0”】。
8.從字串格式化輸入(string scan format):
int sscanf(char*buf,const char*format,…);
用法類似scanf,但是從buf中讀取。成功返回引數數目,失敗返回-1。需包含stdio.h
可以用來將字串轉換成數值或者進行匹配輸入("x=%lf",從中讀取數值)。
sprintf與sscanf函式常用來實現字串與其它資料型別的轉換。