C語言之字串
字串是由數字、字母、下劃線組成的一串字元。一般記為 s=“a1a2···an”(n>=0)。它是程式語言中表示文字的資料型別。在程式設計中,字串(string)為符號或數值的一個連續序列,如符號串(一串字元)或二進位制數字串(一串二進位制數字)。
1、簡介
C語言中沒有字串這種變數型別,要表示一個字串一般採用字元陣列或是字元指標。一個字串以 ‘\0’ 結束。注意在用字元去初始化字元陣列時字元陣列的最後一個字元要用 ‘\0’ 結束,否則在使用時會出錯。用字串初始化則系統會自動在末尾加上 ‘\0’ 。
char str1[] = {'h','e','l','l','o'};
char str2[] = "world" ;
char *str3 = "SUST";
2、相關函式
(1)字串比較
int strcmp(const char* str1,const char* str2);
從頭依次比較字串str1和str2的每個字元,若大於則返回大於0的值,若小於則返回小於0的值,若相等則繼續比較,若全部相等則返回0;實現如下:
int Strcmp(const char *s1, const char *s2){
assert(NULL !=s1 && NULL != s2);
while(*s1 != '\0' && *s2 != '\0' && *s1 ==*s2){
s1++;
s2++;
}
return *s1 - *s2;
}
舉例如下:
#include <stdio.h>
int main()
{
char *s1 = "hello";
char *s2 = "world";
char *s3 = "abcde";
char *s4 = "hello";
printf("%d\n",strcmp(s1,s2));
printf("%d\n",strcmp(s1,s3));
printf ("%d\n",strcmp(s1,s4));
return 0;
}
如果不是對整個字串進行比較而只是比較指定數目的字串,可以使用函式:
int strncmp(const char *s1, const char *s2, size_t n);
用法和返回值都和strcmp類似,之比較給定字串的前n個字元,或者到遇到任一字串結尾。實現如下:
int Strncmp(const char *s1, const char *s2, size_t n){
assert(NULL!=s1 && NULL!=s2);
if(n == 0)
return 0;
size_t cnt = 1;
while(*s1 != '\0' && *s2 != '\0' && *s1==*s2 && cnt < n){
s1++;
s2++;
cnt++;
}
return *s1 - *s2;
}
(2)字串查詢
最簡單的是查詢字串查詢字元:
char *strchr(const char *s, int c);
至於引數為什麼是int,歷史遺留問題,這裡不多討論。函式返回在s中找到的第一個c的位置的指標,注意的是,字串末尾的‘\0’也是可以被查詢的。實現如下:
char *Strchr(const char *s, int n){
assert(s != NULL);
char c = (char)n;
do{
if(*s == c)
return (char *)s;
}while(*s++);
return NULL;
}
還有查詢字串的函式strstr:
char *strstr(const char *s1, const char *s2);
函式返回s2在s1中出現的首字元的位置,實現如下:
char *Strstr(const char *s1, const char *s2){
assert(NULL!=s1 && NULL!=s2);
size_t len = strlen(s2);
while(*s1){
if(!strncmp(s1,s2,len))
return (char *)s1;
s1++;
}
return NULL;
}
(3)字串複製
最常見的字串複製函式是strcpy:
char *strcpy(char *dst, const char *src);
把src所指的由NULL結尾的字串複製到由dst所指的字串中,src和dst不可以相同(可以由c99的restrict關鍵字宣告),dst必有足夠的空間存放複製的字串。還有一點要注意的是函式返回值,返回值是指向dst的指標,這樣做的目的是方便程式中語句內聯,比如strlen(strcpy(s,t))。
函式的實現如下:
char *Strcpy(char *dst, const char *src){
assert(NULL!=dst && NULL!=src);
char *p = dst;
while((*dst++ = *src++) != '\0');
return p;
}
使用strcpy需要注意的是要保證dst所指的空間足夠拷貝src所指的字串大小,否則會造成溢位。所以,在大多數情況下都是用strncpy會更加保險,實現如下:
char *Strncpy(char *dst, const char *src, size_t n){
assert(NULL!=dst && NULL!=src);
char *p = dst;
while(n){
if((*dst++ = *src++) == '\0')
break;
n--;
}
return p;
}
需要注意另外一個函式strdup:
char strdup(const char );
該函式和strcpy的不同是,函式會自己申請記憶體空間存放拷貝的字串,然後返回指向該字串的指標。所以在使用strdup函式時需要注意的是,在使用完複製的字串後使用free函式釋放其佔用的空間。
(4)字串連線
字串連線是把一個字串的頭連線到另一個字串的結尾。
char *strcat(char *s1, const char *s2);
函式的實現如下:
char *Strcat(char *s1, const char *s2){
assert(NULL!=s1 && NULL!=s2);
char *p =s1;
while(*s1)s1++;
strcpy(s1,s2);
return p;
}
同樣,strcat也是不安全的,因為也對緩衝區足夠存放連線的字串進行了假設。所以,多數情況下我們應該使用更安全的:
char *strncat(char *s1, const char *s2, size_t n);