在這一節,我想主要來介紹一下C語言操作字串的常用函數。
C語言的字串函數的原型都駐留在<string.h>標頭檔中,因此我們在處理字串時,需要引入這個標頭檔。
但是,我不希望只是單純地介紹每個函數的用法,如果那樣,看API就可以了,我希望在介紹每個函數時都自己來實現一次。
1. strcpy函數
string copy,我們先來看一下該函數的用法。
#include<stdio.h>#include<string.h>int main(){ char *str1="abcd"; char str2[5]; strcpy(str2,str1); printf("%s",str2); return 0;}
在上段代碼中,我們注意,str2的字串長度應該是5,也就是strlen(“abcd”)加上’\0’。在上面的代碼中,我們將str1的字串複製到了str2中。
我們也來看下,這兩段代碼的區別:
#include<stdio.h>#include<string.h>int main(){ char str1[5]="abcd"; char str2[5]; char *str3=str1; strcpy(str2,str1); str1[1]='t'; printf("str2:%s\n",str2); printf("str3:%s",str3); return 0;}
我們對比結果可以發現他們的不同,在這裡,我們不妨回頭想想Java/C#的深複製和淺複製。
當我們修改第一段代碼為這樣時會發現錯誤:
#include<stdio.h>#include<string.h>int main(){ char str1[5]="abcd"; char str2[3]; strcpy(str2,str1); str1[1]='t'; printf("str2:%s\n",str2); return 0;}
錯誤的原因就是,str2不足以容納下str1的字串,也就是說strcpy我們沒有足夠的控制權,那麼我們就可以來採用strncpy的方法來實現:
#include<stdio.h>#include<string.h>int main(){ char str1[5]="abcd"; char str2[3]; strncpy(str2,str1,sizeof(str2)-1); str2[sizeof(str2)-1]='\0'; printf("str2:%s\n",str2); return 0;}
這個方法就不多說了,就是加上了一個長度控制,接下來我們來試著實現一下簡單的strcpy函數。
#include<stdio.h>#include<string.h>char *mycopy(char *,const char *);int main(){ char str1[5]="abcd"; char str2[5]; mycopy(str2,str1); printf("%s",str2); return 0;}char *mycopy(char *strDest,const char *strSource){ char *temp=strDest; while(*temp++=*strSource++) ; return strDest;}
同理,我們也可以寫出strncpy的代碼:
char *mycopy(char *strDest,const char *strSource,int size){ char *temp=strDest; int i =0; while(i<size) { *temp++=*strSource++; i++; } *temp='\0'; return strDest;}
2. 再談字串的問題
其實我之前一直都沒有想懂關於字串中修改某一字元的問題,我一直很困擾這樣一個問題:
我收回在上一節中說的觀點,其實字串是否能修改取決的是這段字串是否位於常量區。
3. strlen函數
這個很簡單,實現一下:
size_t mylength(char * str){ int count=0; while(*str++) { count++; } return (size_t)count;}
但是如果這樣來寫,每次當指標前移的時候,都需要進行一次加法操作,會對效率造成一定的影響,我們可以這樣來寫:
size_t mylength(char * str){ char *temp=str; while(*temp++) ; return (size_t)(temp-str-1);}
4. strcmp函數
字串比較函數:
int mycompare(const char *str1,const char *str2){ while(*str1==*str2) { if(*str1=='\0') { return 0; } str1++; str2++; } return *str1>*str2?1:-1;}