strlen 這個函數是在 string.h 的頭文件中定義的 它的函數原型是 size_t strlen( const char ); size_t 是一個無符號整型,是這樣定義的 typedef unsigned int size_t; 既然它返回的不是整型數,那么如果你想直接對他的表達式進行操作,那么肯定就會存在一些問題,如下:
if( strlen(str1) - strlen(str2) >=0 )
這個判斷語句將永遠都是真的,因為左側的是無符號數,那個不可能比零小,所以這樣做就和你的預期想法完全不同了。所以對 strlen 的返還值進行強制轉換為 int 類型就不用擔心這種問題的出現。
strcpy 這個函數是 string.h 的頭文件中定義的 它的函數原型是 char * strcpy( char *dst, char const *src); 函數的功能是把 src 字符串復制到 dst ,如果兩參數在內存中出現重疊,那么結果是未定義的。因為 dst 將被修改所以他不可以是字符串常量,這個函數有一個返還值,這個返還值其實就是操作后的字符串指針的一個復制。同時在使用這個函數的時候有一個問題是必須要注意的,保證目標字符數組的空間一定要足以容納需要復制的字符串,如果使用者不能保證這個問題,那么數組后的內存空間將被覆蓋,這樣引起的危害是不可估量的。
strcat 這個函數是 string.h 的頭文件中定義的 它的函數原型是 char * strcat( char * dst, char const *src ); 函數的功能是把 src 字符串添加在 dst 原有字符串的后面,去掉原有的 '\0' 將字符串添加到后面並加上一個 '\0' 。和上一個函數一樣都需要注意的要確保目標字符數組有足夠的空間,返還值也是操作后的字符串的指針。
strcmp 這個函數是 string.h 的頭文件中定義的 它的函數原型是 int strcmp (char const *s1, char const *s2 ); 函數的功能是 將兩個字符串的字符逐一比較,直到發現不匹配為止,那個優先不匹配的較“小”,這種比較叫做字典比較。如果 s1 小於 s2 返回一個小於零的值,如果 s1 大於 s2 ,返回一個大於零的值,如果兩個參數相等返回零。
那么既然這種函數在操作的時候需要考慮到字符數組能否存儲下的問題,那個就有了相應的可以限制長度的函數。
strncpy strncat strncmp
這是三個函數的原型是
char * strncpy( char *dst, char const *src, size_t len );
char * strncat ( char *dst ,char const *src ,size_t len);
int strncmp(char const *s1, char const *s2, size_t len;
這些函數都在原來的基礎上加了一個參數,就是要操作字符串的長度。strncpy 函數從 src 字符串中復制 len 個字符到 dst 中,如果不足就用NUL補充,strncat 函數從 src 中復制 len 個字符到 dst 的后面,最后並加上一個NUL。
strncmp 就是只比較 len 個字符。
strchr和strrchr 這個函數是 string.h 的頭文件中定義的 它們的函數原型是
char * strchr ( char const *str, int ch);
char *strrchr ( char const *str, int ch);
strchr 功能是返回字符第一次出現在字符串中的位置,strrchr 的功能是返回最后一次出現字符串中的位置。如果不存在返回NULL指針。
strpbrk 這個函數是 string.h 的頭文件中定義的 它的函數原型是 char *strpbrk( char const *str, char const *group ); 函數的功能是返回一個指向 str 中第一個匹配 group 中任何一個字符的字符位置,如果未找到返回一個NULL指針。
例:
#include<stdio.h> #include<string.h> int main() { char str[]="Hello World"; printf("%s",strpbrk(str,"aqdlze")); }
ello World
strstr 這個函數是 string.h 的頭文件中定義的 它的函數原型是 char *strstr( char const *s1,char const *s2); 這個函數在s1中查找整個s2第一次出現的位置,並返回一個指向該位置的指針,如果s2沒有完全的出現在s1的任何位置就返回一個NULL指針,如果s2是一個空字符串就返回s1。
strspn 和 strcspn 這兩個函數的原型是:
size_t strspn ( char const *str, char const * group );
size_t strcspn ( char const *str, char const * group );
group 指定一個或多個字符,strspn 返回 str 起始部分匹配 group 中任意字符的字符數。
例如:
#include<stdio.h> #include<string.h> int main() { char *str="bcda adb,123"; printf("%d ",strspn(str,"abcd123")); printf("%d ",strspn(str,"abcd123 ")); printf("%d ",strspn(str,"abcd123 ,")); }
4 8 12
strcspn 的功能正好和 strspn 相反
#include<stdio.h> #include<string.h> int main() { char *str="bcda adb,123"; printf("%d ",strcspn(str,"123")); printf("%d ",strcspn(str,",")); printf("%d ",strcspn(str,"123 ,")); }
9 8 4
strtok 這個函數是 string.h 的頭文件中定義的 它的函數原型是 char * strtok(char *str, const char *sep); sep是分隔字符串集合,str 中包含了零個或多個sep中的一個或多個分隔標記,strtok 的功能就是找出 str 中的下一個標記,並將其用NUL結尾,返回指向這個標記的指針。需要注意的是 str 參數不是只讀的,在函數中它將會被改變,所以如果傳入的參數是不可以改變的,那個就應該提前對這個字符串進行復制,然后再傳入函數中。
#include<stdio.h> #include<string.h> int main() { char str1[]="abc,def ghi,jkl"; char *s1; s1=strtok(str1," ,"); printf("%s\n",str1); printf("%s\n",s1); char str2[]="123 def\nasd"; char *s2; s2=strtok(str2,"\n"); printf("%s\n",str2); printf("%s",s2); }
abc abc 123 def 123 def
那么這樣就會出現一個問題,因為加了一個NUL所以字符串只后面的部分訪問不到了,我想這和你最初的想法肯定背道而馳了,那么應該如何解決這個問題那?
請看下面一段代碼:
#include<stdio.h> #include<string.h> void print_tok(char *line,char const *sign) { char *tok; for( tok = strtok(line, sign); tok != NULL; tok = strtok(NULL, sign) ) { printf("%s\n",tok); } } int main() { char str[]="asd zxc qwe"; print_tok(str," "); }
asd zxc qwe
為什么會這樣,因為如果 strtok 的第一個參數是NULL函數就在同一個字符串中從保存的位置開始像前面一樣查找下一個標記,如果字符串中不存在更多的標記,就返回一個NULL指針。strtok 函數會保存它的處理狀態的局部信息,所以在處理完一個字符串前不可以處理另一個字符串。
strerror 這個函數是 string.h 的頭文件中定義的 它的函數原型是 char *strerror( int error_number ); 這個函數的參數是一個外部整型變量 errno ,在你調用函數出現錯誤的時候就會通過 errno 這個變量作為 strerror 的參數,並返回一個指向描述錯誤的字符串的指針。
#include<stdio.h> #include<string.h> #include<stdlib.h> int main() { FILE *fp; fopen("aaa","r"); printf("%s",strerror(errno)); }
No such file or directory
字符分類函數:
每個分類函數接收一個包含字符的整型參數,函數測試這個字符並返回一個整型值,表示真或假(ANSI C標准並沒有指定任何特定值,所以可能返回任何非零值,所以不要和1進行比較,不然可能出現不可預料的結果)。
分類函數如下表:
引用自《C和指針》
字符轉換函數:
int tolower( int ch ); 返回參數轉換成對應的小寫字母。
int toupper( int ch ); 返回參數轉換成對應的大寫字母。
如果傳入的參數不需要進行操作或無法進行操作,不進行修改參數直接返回。
內存操作(字節操作)函數:
char *memcpy( void *dst, void const *src, size_t length );
char *memmove( void *dst, void const *src, size_t length );
char *memcmp( void const *a,void const *b, size_t length);
char *memchr( void const *a, int ch, size_t length );
char *memset( void *a ,int ch, size_t length );
字符串函數在處理字符串的時候,遇到NUL就會停止,但是非字符串中有很多包含NUL的情況,那個就用到了上面的函數了。memcpy 實現的就是將 src 的數據 length 個復制到 dst 中,同時如果是整型或浮點數組,那么也不用進行強制轉換,因為函數的參數是void的類型指針,所有類型的指針都可以接收,和 strcpy 相同的如果兩個參數在內存中有重疊的部分,那么結果是未定義的。
但是 memmove 就解決了這個問題,它實現的功能和 memcpy 是相似的,但是它是先將第二個參數要復制的內容復制到另外的一個變量中,然后再復制給第一個參數。
memcmp 和 strcmp 比較方式相同,但是如果比較的內容不是字母范圍內的東西,那么結果是不可預料的。
memchr 就是在第一參數中查找第一個 包含字符的參數 ch 的位置,並返回它的指針。
memset 的功能是將 ch 字符從第一個參數的開始進行填充,填充 length 個字節。