盤點分析C語言中少見卻強大的字符串函數(shù)
正片開始
字符串函數(shù)
首先神魔是字符串函數(shù)?
指的是編程語言中用來進行字符串處理的函數(shù),如C,pascal,Visual以及LotusScript中進行字符串拷貝,計算長度,字符查找等的函數(shù)。 功能:把src所指由NUL結(jié)束的字符串復制到dest所指的 數(shù)組 中。 返回指向dest結(jié)尾處字符 (NUL)的 指針 。
像之前我寫到過的 strcpy,strcat,strcmp 這些函數(shù)都屬于長度不受限的字符串函數(shù),由此就有下面兩種分類
1.長度不受限的字符串函數(shù)
2.長度受限的字符串函數(shù)
長度不受限就是以‘ \0 ’為函數(shù)結(jié)束標準的判定,當對象沒給定 ’ \0 '時,就跑不出結(jié)果或者報錯;相反則為長度受限。我再整理一下,好做個對比:
strcpy
字符串拷貝,把指向的字符串復制到目標字符串,聲明為
char *strcpy(char *dest, const char *src)
strcat
字符串連續(xù),把指向的字符串追加到目標字符串的結(jié)尾(無間隔),聲明為:
char *strcat(char *dest, const char *src)
strcmp
把所指向的字符串和目標字符串進行比較, 返回值大小決定二者的相對大小,聲明如下:
int strcmp(const char *str1, const char *str2)
以上三種是函數(shù)的長度受限,我們可以變 strncpy,strncat 和 strncmp,就是長度不受限函數(shù)了,相比多了一個 n ,這個 n 是指函數(shù)作用范圍最多在前 n 個字節(jié),比如 strncmp 中的n 就是要比較的最大字符數(shù),就相當于一個限制機制了。
這里主要補充幾個比較實用的吧:
strstr
其實顧名思義,翻譯過來就是“字符串字符串”,其實作用就是在一個字符串里面找我的目標字符串,不包含終止符 ‘\0’,返回值是該函數(shù)在 目標字符串中第一次出現(xiàn)該字符串的位置。聲明為:
char *strstr(const char *haystack, const char *needle)
舉個栗子:
int main() { char a[] = "overwatch"; char b[] = "wa"; char* c = strstr(a, b); if (c != NULL) { printf("found it: %s\n", c); } else { printf("there was nothing\n"); } return 0; }
我們用最常規(guī)的代碼也可以模擬出 strstr 的功能,庫函數(shù)的實現(xiàn)方法也是類似
#include<assert.h> char* strstr1(const char* a, const char* b) { assert(a && b); const char* c = NULL; const char* d = NULL; const char* str = a; if (*b == '\0') { return (char*)a; //處理查找語句為空語句 } while (*str) { c = str; d = b; while (*c && *d && (*c == *d))//防止相同元素為'\0' 循環(huán)繼續(xù)導致越界訪問 { *c++; *d++; } if (*d == '\0') { return (char*)str; } str++;//多次查找,匹配錯誤會回到起點++再重新查找 } return NULL; }
要注意的是,該函數(shù)規(guī)定當查找對象字符串為空 (\0) 時,會返回目標字符串的地址。
KMP算法
說到了 strstr ,引申一下KMP算法,也就是字符串查找算法,稱之為 Knuth-Morria-Pratt 算法。該算法相對于暴力算法有比較大的改進,主要是消除了主串指針的回溯,從而使算法效率有了某種程度的提高。KMP算法比我們的 strstr 效率要高,我們?nèi)蘸笤偌毤氈v解
strtok
我們可以稱之為字符串刀,作用就是分割字符串,strtok() 函數(shù)的聲明如下:
char *strtok(char *str, const char *delim)
str 為一組字符串,delim 為分隔符,也可以是個集合,分割結(jié)果變成第一個子字符串。
因為結(jié)果被修改所以 strtok 對象一般為臨時拷貝的可修改內(nèi)容。舉個栗子:
int main() { char a[] = "overwatch"; char b[20] = { 0 }; char* ret = NULL; strcpy(b, a); //進行臨時拷貝方便切割 char* p = "w";//指針類型維護分隔符 ret = strtok(b, p); printf("%s\n", ret); return 0; }
若要進一步分割,我們需要空指針進行維護,什么意思?
分割完一次,結(jié)尾就會變成 ‘ \0 ’,此時的 strtok 記憶能力已經(jīng)記住了 ‘ \0 ’的位置,這個記憶功能我們大致都能猜出是一個靜態(tài)變量,static 修飾一個局部變量時就可以做到這點,就是我們只需要傳入一個 null ,就可以自動進行分割,以此類推:
strtok(b, p); ret = strtok(NULL,"t");
strerror
咱在使用庫函數(shù)時,總會有調(diào)用失敗的時候,這時候都會有一個錯誤碼被設(shè)置,這個錯碼都會放進 errno 這個全局錯誤碼里面,我們看到的錯誤信息可能是一個莫名其妙的數(shù)字,而 strerror 就是將錯誤碼翻譯成錯誤信息,并返回一個指向錯誤消息字符串的指針。strerror 生成的錯誤字符串取決于開發(fā)平臺和編譯器。
char *strerror(int errnum)
比如:
int main() { printf("%s\n", strerror(10)); printf("%s\n", strerror(20)); printf("%s\n", strerror(30)); return 0; }
結(jié)果分別是:無子進程,非目錄元素,只讀文件系統(tǒng)
但其實 strerror 并不是小題大做拿來查詢錯誤的,是在文本上輸入輸出時方便我們得知打開寫入打開失敗的原因的,當我們嘗試打開一個不存在的文件時就會報錯: No such file or directory
#include <errno.h> int main () { FILE *fp; fp = fopen("file.txt","search"); if( fp == NULL ) { printf("Error: %s\n", strerror(errno)); } return(0); }
因為我們要調(diào)用C語言給出的全局變量 errno,所以記得要引 <errno.h> 頭文件。
以上就是盤點分析C語言中少見卻強大的字符串函數(shù)的詳細內(nèi)容,更多關(guān)于C語言字符串函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Cocos2d-x UI開發(fā)之CCControlButton控件類實例
這篇文章主要介紹了Cocos2d-x UI開發(fā)之CCControlButton控件類實例,本文代碼中包含大量注釋來講解CCControlButton控件類的使用,需要的朋友可以參考下2014-09-09C語言中fgetgrent()函數(shù)和fgetpwent()函數(shù)的用法對比
這篇文章主要介紹了C語言中fgetgrent()函數(shù)和fgetpwent()函數(shù)的用法對比,分別用于讀取組格式函數(shù)和讀取密碼格式,需要的朋友可以參考下2015-08-08C++深入刨析優(yōu)先級隊列priority_queue的使用
最近我學習了C++中的STL庫中的優(yōu)先級隊列(priority_queue)容器適配器,對于優(yōu)先級隊列,我們不僅要會使用常用的函數(shù)接口,我們還有明白這些接口在其底層是如何實現(xiàn)的2022-08-08C語言中關(guān)于庫函數(shù) qsort 快排的用法
快速排序Qsort是所有學習算法和數(shù)據(jù)結(jié)構(gòu)最基礎(chǔ)的一個部分,也是考試題和面試的一個小重點。本片文章帶你了解Qsort的詳細用法規(guī)則2021-09-09