C語言字串處理函數

來源:互聯網
上載者:User

 這邊文章對c語言的字串處理的常用庫函數總結一下,並進行實現。

1.字串比較

int strcmp(const char *s1, const char *s2);

比較兩個字串的大小(不忽略大小寫),傳回值很有學問:如果s1小於s2返回一個小於0的數,如果s1大於s2返回一個大於0的數,如果相等則返回0。傳回值是兩個字串中第一個不相等的字元ascii碼的差值。實現如下:

int my_strcmp(const char *s1, const char *s2){//important! validate arguments first!assert(NULL !=s1 && NULL != s2);while(*s1 != '\0' && *s2 != '\0' && *s1==*s2){s1++;s2++;}return *s1 - *s2;}

注意再函數開始進行參數檢查,防止輸入參數有NULL時發生執行階段錯誤。

strcmp是最常用的字串比較函數,一般用法是if(!strcmp(s1, s2)){ ...}。如果不是對整個字串進行比較而只是比較指定數目的字串,可以使用函數:

int strncmp(const char *s1, const char *s2, size_t n);

用法和傳回值都和strcmp類似,之比較給定字串的前n個字元,或者到遇到任一字串結尾。實現如下:

int my_strncmp(const char *s1, const char *s2, size_t n){//important! validate arguments first!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;}

需要注意的除了參數檢查外,還要注意n=0的特殊情況,這裡我們n=0永遠返回0。

還有其他一些帶特殊要求字串比較函數,如:

stricmp,memcmp,memicmp等等,加i表示比較時忽視大小寫,帶mem的是比較一塊記憶體區間。

2.字串尋找

最簡單的是尋找字串尋找字元:

char *strchr(const char *s, int c);

至於參數為什麼是int,曆史遺留問題,這裡不多討論。函數返回在s中找到的第一個c的位置的指標,注意的是,字串末尾的‘\0’也是可以被尋找的。實現如下:

char *my_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 *my_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;}

c標準庫中並沒有定義類似strnchr和strnstr的限定尋找範圍的函數,當然需要的話我們可以自己定義,如:

char *strnstr(const char* s1, const char* s2, size_t n){  const char* p;  size_t len = strlen(s2);  if (len == 0) {    return (char *)s1;  }  for (p = s1; *p && (p + len<= buffer + n); p++) {    if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {      return (char *)p;    }  }  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 *my_strcpy(char *dst, const char *src){assert(NULL!=dst && NULL!=src);char *p = dst;while((*dst++ = *src++) != '\0');return p;}

使用strcpy是危險的,因為函數本身是不檢查dst指向的空間是否足夠儲存需要複製的字串,導致的一個潛在隱患就是字串溢出。這也是上個世紀常被駭客利用的一個經典漏洞。所以,在大多數情況下都是用strncpy無疑更加保險:

char *my_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函數釋放其佔用的空間。

另memcpy函數和strncpy類似,只是不會再遇到NULL時終止拷貝,該函數一定會拷貝n個字元。

4.字串串連

字串串連是把一個字串的頭串連到另一個字串的結尾。

char *strcat(char *s1, const char *s2);

函數的實現如下:

char *my_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);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.