與字串與記憶體相關的庫函式
技術標籤:學習過程
本次部落格寫的是關於幾個庫函式的實現的使用,這些函式都是提前包含在標準庫中的,不需要我們自己定義,我們要學的是關於它們的使用。
在使用庫函式是應當注意兩點問題:
- 要包含庫函式所在的標頭檔案
- 要注意引數合法性檢驗
這兩點問題在下面我們會提到。
引數合法性檢驗
當使用庫函式時,要注意引數的合法性檢驗,以免傳入錯誤引數而導致BUG的出現。
引數合法性檢驗的兩種風格:
1.if else;
2.assert (表示式);斷言,寫一個表示式,如果表示式為真,斷言沒有任何效果,程式碼繼續執行;如果表示式為假,程式就會直接崩潰。使用的時候要包含<assert.h>標頭檔案。
引數合法性判定的注意事項:
1.一般拿引數和空指標判定,雖然沒啥卵用,但是聊勝於無。(有些合法性檢驗沒啥用,但是必須寫,要讓別人知道你有引數合法性檢驗這個意識)。
2.判定的時候有兩種風格,該怎麼選?
assert:是一種比較嚴厲的處理方式,一旦觸發,程式就會崩潰,如果當前場景是比較嚴重的問題,適合使用assert;例如:伺服器啟動,載入資料發現數據丟失了;在進行金錢結算的時候出現的問題等等。
if:如果當前場景沒那麼嚴重的問題,就不應該使用assert,而應該使用if,來自行定義問題處理方式。
字串函式
下面介紹一些關於字串操作的庫函式,使用這些庫函式會大大提高我們寫程式碼的效率,將許多複雜的迴圈和過程在這些這些庫函式裡實現,這些庫函式同時需要包含標頭檔案 <string.h>,
下面將來一一介紹
1. strlen
描述:
C 庫函式 size_t strlen(const char *str)
計算字串 str 的長度,直到空結束字元,但不包括空結束字元。
宣告:
下面是 strlen() 函式的宣告。
size_t strlen(const char *str)
引數:
str -- 要計算長度的字串。
返回值:
該函式返回字串的長度。
例項:
下面的例項演示了 strlen() 函式的用法。
#include <stdio.h>
#include <string.h>
int main ()
{
char str[50];
int len;
strcpy(str, "This is runoob.com");
len = strlen(str);
printf("|%s| 的長度是 |%d|\n", str, len);
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
|This is runoob.com| 的長度是 |18|
模擬strlen的實現
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}
//不能建立臨時變數計數器
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
//指標-指標的方式
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
2. strcpy()
描述:
C 庫函式 char *strcpy(char *dest, const char *src
) 把 src 所指向的字串複製到 dest。
需要注意的是如果目標陣列 dest 不夠大,而源字串的長度又太長,可能會造成緩衝溢位的情況。
宣告
下面是 strcpy() 函式的宣告。
char *strcpy(char *dest, const char *src)
引數:
dest -- 指向用於儲存複製內容的目標陣列。
src -- 要複製的字串。
返回值:
該函式返回一個指向最終的目標字串 dest 的指標。
例項
下面的例項演示了 strcpy() 函式的用法。
例項:
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[100];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is runoob.com");
strcpy(dest, src);
printf("最終的目標字串: %s\n", dest);
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
最終的目標字串: This is runoob.com
```c
****模擬實現strcpy:****
/1.引數順序
//2.函式的功能,停止條件
//3.assert
//4.const修飾指標
//5.函式返回值
//6.題目出自《高質量C/C++程式設計》書籍最後的試題部分
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
3. strncpy()
描述:
C 庫函式 char *strncpy(char *dest, const char *src, size_t n) 把 src 所指向的字串複製到 dest,最多複製 n 個字元。當 src 的長度小於 n 時,dest 的剩餘部分將用空位元組填充。
宣告
下面是 strncpy() 函式的宣告。
char *strncpy(char *dest, const char *src, size_t n)
引數:
dest -- 指向用於儲存複製內容的目標陣列。
src -- 要複製的字串。
n -- 要從源中複製的字元數。
返回值:
該函式返回最終複製的字串。
例項:
下面的例項演示了 strncpy() 函式的用法。在這裡,我們使用函式 memset() 來清除記憶體位置。
例項:
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is runoob.com");
strncpy(dest, src, 10);
printf("最終的目標字串: %s\n", dest);
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
最終的目標字串: This is ru
模擬實現strncpy
char* Strncpy(char* destination, const char* source, size_t num)
{
assert(destination != NULL);
assert(source != NULL);
size_t i = 0;
while(i < num && source[i] != '\0')
{
destination[i] = source[i];
i++;
}
if(i == num)
{
return destination;
}
if(source[i] == '\0')
{
for(; i < num; i++)
{
destination[i] = '\0';
}
return destination;
}
}
4. strcat()
描述:
C 庫函式 char *strcat(char *dest, const char *src) 把 src 所指向的字串追加到 dest 所指向的字串的結尾。
宣告
下面是 strcat() 函式的宣告。
char *strcat(char *dest, const char *src)
引數:
dest -- 指向目標陣列,該陣列包含了一個 C 字串,且足夠容納追加後的字串。
src -- 指向要追加的字串,該字串不會覆蓋目標字串。
返回值
該函式返回一個指向最終的目標字串 dest 的指標。
例項:
下面的例項演示了 strcat() 函式的用法。
例項
#include <stdio.h>
#include <string.h>
int main ()
{
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strcat(dest, src);
printf("最終的目標字串: |%s|", dest);
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
最終的目標字串: |This is destinationThis is source|
模擬實現strcat
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while(*dest)
{
dest++;
}
while((*dest++ = *src++))
{
;
}
return ret;
}
5. strncat()
描述:
C 庫函式 char *strncat(char *dest, const char *src, size_t n) 把 src 所指向的字串追加到 dest 所指向的字串的結尾,直到 n 字元長度為止。
宣告:
下面是 strncat() 函式的宣告。
char *strncat(char *dest, const char *src, size_t n)
引數:
dest -- 指向目標陣列,該陣列包含了一個 C 字串,且足夠容納追加後的字串,包括額外的空字元。
src -- 要追加的字串。
n -- 要追加的最大字元數。
返回值:
該函式返回一個指向最終的目標字串 dest 的指標。
例項:
下面的例項演示了 strncat() 函式的用法。
#include <stdio.h>
#include <string.h>
int main ()
{
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strncat(dest, src, 15);
printf("最終的目標字串: |%s|", dest);
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
最終的目標字串: |This is destinationThis is source|
模擬實現strncat
char* Strncat(char* destination, const char* source, size_t num)
{
assert(destination != NULL);
assert(source != NULL);
size_t i = 0;
while(destination[i] != '\0')
{
i++;
}
size_t j = 0;
while(j < num && source[j] != '\0')
{
destination[i] = source[j];
j++;
i++;
}
destination[i] = '\0';
return destination;
}
6. strcmp()
描述:
C 庫函式 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字串和 str2 所指向的字串進行比較。
宣告
下面是 strcmp() 函式的宣告。
int strcmp(const char *str1, const char *str2)
引數:
str1 -- 要進行比較的第一個字串。
str2 -- 要進行比較的第二個字串。
返回值:
該函式返回值如下:
如果返回值小於 0,則表示 str1 小於 str2。
如果返回值大於 0,則表示 str1 大於 str2。
如果返回值等於 0,則表示 str1 等於 str2。
例項:
下面的例項演示了 strcmp() 函式的用法。
例項
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strcmp(str1, str2);
if(ret < 0)
{
printf("str1 小於 str2");
}
else if(ret > 0)
{
printf("str1 大於 str2");
}
else
{
printf("str1 等於 str2");
}
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
str1 大於 str2
模擬實現strcmp
int my_strcmp (const char * src, const char * dst)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
7. strncmp()
描述:
C 庫函式 int strncmp(const char *str1, const char *str2, size_t n) 把 str1 和 str2 進行比較,最多比較前 n 個位元組。
宣告
下面是 strncmp() 函式的宣告。
int strncmp(const char *str1, const char *str2, size_t n)
引數:
str1 -- 要進行比較的第一個字串。
str2 -- 要進行比較的第二個字串。
n -- 要比較的最大字元數。
返回值:
該函式返回值如下:
如果返回值 < 0,則表示 str1 小於 str2。
如果返回值 > 0,則表示 str2 小於 str1。
如果返回值 = 0,則表示 str1 等於 str2。
例項:
下面的例項演示了 strncmp() 函式的用法。
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 4);
if(ret < 0)
{
printf("str1 小於 str2");
}
else if(ret > 0)
{
printf("str2 小於 str1");
}
else
{
printf("str1 等於 str2");
}
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
str2 小於 str1
模擬實現strncmp
int Strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1 != NULL);
assert(str2 != NULL);
size_t i = 0;
while(str1[i] == str2[i] && i < num && str1[i] != '\0' && str2[i] != '\0')
{
i++;
}
if(i == num)
{
return 0;
}
if(str1[i] == '\0' && str2[i] == '\0')
{
return 0;
}
if(str1[i] > str2[i])
{
return 1;
}
if(str1[i] < str2[i])
{
return -1;
}
}
8. strsr
描述:
C 庫函式 char *strstr(const char *haystack, const char *needle) 在字串 haystack 中查詢第一次出現字串 needle 的位置,不包含終止符 ‘\0’。
宣告
下面是 strstr() 函式的宣告。
char *strstr(const char *haystack, const char *needle)
引數:
haystack -- 要被檢索的 C 字串。
needle -- 在 haystack 字串內要搜尋的小字串。
返回值:
該函式返回在 haystack 中第一次出現 needle 字串的位置,如果未找到則返回 null。
例項:
下面的例項演示了 strstr() 函式的用法。
例項
#include <stdio.h>
#include <string.h>
int main()
{
const char haystack[20] = "RUNOOB";
const char needle[10] = "NOOB";
char *ret;
ret = strstr(haystack, needle);
printf("子字串是: %s\n", ret);
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
子字串是: NOOB
模擬實現strstr
char *my_strstr(const char* str1, const char* str2 )
{
assert(str1);
assert(str2);
char *cp = (char*)str1;
char *substr = (char *)str2;
char *s1 = NULL;
if(*str2 == '\0')
return NULL;
while(*cp)
{
s1 = cp;
substr = str2;
while(*s1 && *substr && (*s1 == *substr))
{
s1++;
substr++;
}
if(*substr == '\0')
return cp;
cp++;
}
}
9. strtok
描述:
C 庫函式 char *strtok(char *str, const char *delim) 分解字串 str 為一組字串,delim 為分隔符。
宣告
下面是 strtok() 函式的宣告。
char *strtok(char *str, const char *delim)
引數:
str -- 要被分解成一組小字串的字串。
delim -- 包含分隔符的 C 字串。
返回值:
該函式返回被分解的第一個子字串,如果沒有可檢索的字串,則返回一個空指標。
例項:
下面的例項演示了 strtok() 函式的用法。
例項
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
/* 獲取第一個子字串 */
token = strtok(str, s);
/* 繼續獲取其他的子字串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
讓我們編譯並執行上面的程式,這將產生以下結果:
This is
www.runoob.com
website