C語言字符函數(shù)和字符串函數(shù)示例詳解
一、函數(shù)介紹
1.1 strlen
求字符串長度函數(shù)
size_t strlen(const char* str)
參數(shù)和返回值介紹:
const char* str:要求長度的字符串
返回值:返回字符串的長度,類型為無符號整型
1.1.1 字符串以'\0'作為結(jié)束標(biāo)志,strlen函數(shù)返回的是字符串中'\0'前面出現(xiàn)的字符個數(shù)(不包含'\0')。
1.1.2 指向的字符串必須包含'\0',否則可能會返回隨機(jī)值。
1.1.3 返回的類型是size_t也就是無符號整型。
strlen的簡易模擬實(shí)現(xiàn):
size_t my_strlen(const char* str)
{
assert(str);
size_t count = 0;
while (*str++)
{
count++;
}
return count;
}1.2 strcpy
字符串拷貝函數(shù)
char* strcpy(char* destination, const char* source)
參數(shù)和返回值介紹:
const char* source:源字符串
char* destination:目標(biāo)空間
返回值:返回目標(biāo)空間的地址
1.2.1 源字符串必須以'\0'結(jié)尾。
1.2.2 會將源字符串中的'\0'拷貝到目標(biāo)空間中。
1.2.3 目標(biāo)空間必須足夠大,以確保能夠存放源字符串。
1.2.4 目標(biāo)空間必須可變,不能是常量字符串。
strcpy的簡易模擬實(shí)現(xiàn):
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* tmp = dest;
while (*dest++ = *src++)
{
;
}
return tmp;
}1.3 strcat
字符串追加函數(shù)
char* strcat(char* destinaion, const char* source)
參數(shù)和返回值介紹:
const char* source:源字符串
char* destination:目標(biāo)空間
返回值:返回目標(biāo)空間的地址
1.3.1 源字符串必須以'\0'結(jié)尾。
1.3.2 目標(biāo)空間必須足夠大,能夠容納下源字符串的內(nèi)容。
1.3.3 目標(biāo)空間必須可修改。
1.3.4 字符串不能自己給自己追加。

注:當(dāng)自己給自己追加后src就會永遠(yuǎn)找不到'\0'的位置,從而停不下來了。
strcat的簡易模擬實(shí)現(xiàn):
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* tmp = dest;
while (*dest)
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return tmp;
}1.4 strcmp
字符串比較函數(shù)
int strcmp(const char* str1, const char* str2)
參數(shù)和返回值介紹:
str1和str2:要進(jìn)行比較的兩個字符串
返回值:當(dāng)str1>str2時,返回一個大于0的數(shù)
當(dāng)str1<str2時,返回一個小于0的數(shù)
當(dāng)str1和str2相等時,返回0
strcmp的簡易模擬實(shí)現(xiàn):
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}1.5 strncpy
指定長度的字符串拷貝函數(shù)
char* strcpy(char* destination, const char* source, size_t num)
參數(shù)和返回值介紹:
const char* source:源字符串
char* destination:目標(biāo)空間
size_t num:要拷貝的字符個數(shù)
返回值:返回目標(biāo)空間的地址
1.5.1 拷貝num個字符從源字符串到目標(biāo)空間。
1.5.2 如果源字符串長度小于num,在拷貝完源字符串后,在目標(biāo)空間的后面追加0,直到num個。
當(dāng)源字符串長度小于num時:

strncpy的簡易模擬實(shí)現(xiàn):
char* my_strncpy(char* dest, const char* src, size_t num)
{
assert(dest && src);
char* tmp = dest;
int num1 = num;
while (num1-- && (*dest++ = *src++))
{
;
}
if (num1>0)
{
while (num1--)
{
*dest++ = '\0';
}
}
*dest = '\0';
return tmp;
}1.6 strncat
指定追加字符個數(shù)函數(shù)
char* strncat(char* destinaion, const char* source, size_t num)
參數(shù)和返回值介紹:
const char* source:源字符串
char* destination:目標(biāo)空間
size_t num:要拷追加的字符個數(shù)
返回值:返回目標(biāo)空間的地址
1.6.1 向目標(biāo)空間追加n個屬于源字符串的字符。
1.6.2 當(dāng)源字符串長度小于n時,將不在追加,后面直接加一個'\0'。
strncat的簡易模擬實(shí)現(xiàn):
char* my_strncat(char* dest, const char* src, size_t num)
{
assert(dest && src);
char* tmp = dest;
while (*dest)
{
dest++;
}
while (num)
{
*dest++ = *src++;
num--;
if (*src == '\0')
{
break;
}
}
*dest = '\0';
return tmp;
}1.7 strncmp
比較前n個字符的大小函數(shù)
int strncmp(const char* str1, const char* str2, size_t num)
參數(shù)和返回值介紹:
str1和str2:要進(jìn)行比較的兩個字符串
size_t num:要比較的字符個數(shù)
返回值:當(dāng)str1>str2時,返回一個大于0的數(shù)
當(dāng)str1<str2時,返回一個小于0的數(shù)
當(dāng)str1和str2相等時,返回0
strncmp的簡易模擬實(shí)現(xiàn):
int my_strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1 && str2);
while (num && (*str1 == *str2))
{
num--;
str1++;
str2++;
}
//只有num等于0時str1才會和str2的前num個字符相等
//否則要么是num還沒到0,*str1就和*str2不相等了
if (num == 0)
{
return 0;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}1.8 strstr
字符串找子串函數(shù)
char* strstr(const char* str1, const char* str2)
參數(shù)和返回值介紹:
str1和str2:在字符串str1中找到str2第一次出現(xiàn)的位置
返回值:找到了就返回str1第一次找到str2后的位置,找不到返回NULL
strstr的簡易模擬實(shí)現(xiàn):
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* ch = (char*)str1;
char* s1 = NULL;
char* s2 = NULL;
//結(jié)束條件是ch為\0
while (*ch)
{
s1 = ch;
s2 = (char*)str2;
while (*s1&&*s2&&(*s1 == *s2))
{
s1++;
s2++;
}
//當(dāng)s2為'\0'時就找到了子串
if (*s2 == '\0')
{
return ch;
}
ch++;
}
return NULL;
}1.9 strtok
分割字符串
char* strtok(char* str, const char* sep)
參數(shù)和返回值介紹:
char* str:需要進(jìn)行分割的字符串
const char* sep:分隔符
1.9.1 sep是一個字符串,定義了用作分隔符的字符合集。
1.9.2 第一個參數(shù)指定一個字符串,它包含0個或多個由sep字符串中一個或多個分隔符分割的標(biāo)記。
1.9.3 strtok會找到str的下一個標(biāo)記,并將其替換成\0,返回一個指向這個標(biāo)記的指針。(注:strtok函數(shù)會改變被操作的字符串,所以在使用strtok函數(shù)切分的字符串一般都是臨時拷貝內(nèi)容,并且可以被修改)
1.9.4 strtok第一個參數(shù)不為NULL,strtok函數(shù)將找到str中的第一個標(biāo)記,strtok將保存它在字符串中的位置。
1.9.5 strtok第一個參數(shù)為NULL,strtok函數(shù)將在同一個字符串中被保存的位置開始,查找下一個標(biāo)記。
1.9.6 如果字符串中不包含更多標(biāo)記,將返回NULL。
使用方法:
char arr[] = "helloworld@yeah.net";
char sep[] = "@.";
char tmp[30];
strcpy(tmp, arr);
char* ret = strtok(arr, sep); //第一次傳參需要傳字符串,最好傳一個臨時拷貝的字符串
printf("%s\n", ret);
ret = strtok(NULL, sep); //除了第一次需要傳字符串之外,剩下的只需要傳NULL就行
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);在不知道具體有多少分隔符時的使用方法:
char arr[] = "helloworld@yeah.net#yyy";
char sep[] = "@.#";
char tmp[30];
strcpy(tmp, arr);
char* ret = NULL;
for (ret = strtok(tmp, sep); ret != NULL;ret=strtok(NULL,sep))
{
printf("%s\n", ret);
}1.10 strerror
庫函數(shù)在執(zhí)行的時候如果發(fā)生了錯誤,會將一個錯誤碼存放在errno這個變量中,errno是C語言提供的一個全局變量。
提供錯誤碼,輸出錯誤碼對應(yīng)的錯誤信息
char* strerror(int errnum)
需要包含的頭文件#include<errno.h>
使用方法:

perror相較于strerror來說能夠更徹底的打印錯誤信息。
perror("fopen");字符串分類函數(shù)
頭文件:#include<ctype.h>
| 函數(shù) | 如果判斷結(jié)果為真就返回一個非0的數(shù),判斷結(jié)果為假就返回0 |
| iscntrl | 任意控制字符 |
| isspace | 空格字符:空格' '、換頁'\f'、換行'\n'、回車'\r'、制表符'\t'、垂直制表符'\v' |
| isdigit | 十進(jìn)制數(shù)字0~9 |
| isxdigit | 十六進(jìn)制數(shù)字,包括所有十進(jìn)制數(shù)字0~9,小寫字母a~f,大寫字母A~F |
| islower | 小寫字母a~z |
| isupper | 大寫字母A~Z |
| isalpha | 字母a~z或A~Z |
| isalnum | 字母或數(shù)字,a~z,A~Z,0~9 |
| ispunct | 標(biāo)點(diǎn)符號,任何不屬于數(shù)字或字母的可打印符號 |
| isgraph | 任何圖形字符 |
| isprint | 任何可打印字符,包括圖形字符和空白字符 |
字符轉(zhuǎn)換:
int tolower(int c); //將大寫字母轉(zhuǎn)換成小寫字母 int toupper(int c); //將小寫字母轉(zhuǎn)換成大寫字母
1.11 memcpy
內(nèi)存拷貝函數(shù)
void* memcpy(void* destaintion,const void* source,size_t num)
參數(shù)和返回值介紹:
void* destaintion:目的地
const void* source:源
size_t num:要拷貝的字節(jié)個數(shù)
返回值:返回目標(biāo)空間的起始地址
1.11.1 memcpy從sourec的位置開始向后復(fù)制num個字節(jié)的數(shù)據(jù)到destaintion的內(nèi)存位置。
1.11.2 這個函數(shù)并不關(guān)心'\0',在遇到'\0'時并不會停下來。
1.11.3 memcpy是專門用來處理不相關(guān),不重疊的內(nèi)存拷貝的,如果source和destination有任何的內(nèi)容重疊了,那么結(jié)果是不可預(yù)測的。
1.11.4 source和destination的傳參類型最好要保持一致,可以傳不同類型的,但結(jié)果是不可預(yù)測的。
memcpy的簡易模擬實(shí)現(xiàn):
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
while (num--)
{
*((char*)dest) = *((char*)src);
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}1.12 memmove
內(nèi)存拷貝函數(shù)
void* memmove(void* destaintion,const void* source,size_t num)
參數(shù)和返回值介紹:
void* destaintion:目的地
const void* source:源
size_t num:要拷貝的字節(jié)個數(shù)
返回值:返回目標(biāo)空間的起始地址
1.12.1 和memcpy的區(qū)別在于memmove能額外處理內(nèi)容重疊的拷貝。
1.12.2 如果源空間和目標(biāo)空間發(fā)生了重疊,就得使用memmove來處理。
memmove的使用場景:

memmove的簡易模擬實(shí)現(xiàn):

void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
//從前往后拷貝
while (num--)
{
*((char*)dest) = *((char*)src);
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//從后往前拷貝
while (num--)
{
*((char*)dest+num) = *((char*)src+num);
}
}
return ret;
}1.13 memcpy
內(nèi)存比較函數(shù)
int memcmp(const void* ptr1,const void* ptr2,size_t num)
參數(shù)和返回值介紹:
ptr1和ptr2:要進(jìn)行比較的兩組內(nèi)存中的數(shù)據(jù)
num:要比較的字節(jié)個數(shù)
返回值:ptr1>ptr2返回一個大于0的數(shù)字
ptr1==ptr2返回0
ptr1<ptr2返回一個小于0的數(shù)字
1.13.1 只比較前num個字節(jié)大小。
1.13.2 memset是一對字節(jié)一對字節(jié)依次進(jìn)行比較的。
1.14 memset
內(nèi)存設(shè)置函數(shù)
void* memset(void* ptr,int value,size_t num)
參數(shù)和返回值介紹:
ptr:要設(shè)置的內(nèi)存空間
value:要設(shè)置的值
num:設(shè)置的字節(jié)個數(shù)
返回值:返回指向的內(nèi)存空間
1.14.1 memset內(nèi)存設(shè)置是以字節(jié)為單位設(shè)置的。
總結(jié)
到此這篇關(guān)于C語言字符函數(shù)和字符串函數(shù)的文章就介紹到這了,更多相關(guān)C語言字符函數(shù)和字符串函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++獲取多瀏覽器上網(wǎng)歷史記錄示例代碼(支持獲取IE/Chrome/FireFox)
這篇文章主要介紹了C++獲取多瀏覽器上網(wǎng)歷史記錄示例代碼,支持獲取IE, Chrome,FireFox等瀏覽器2013-11-11
Qt creator中項目的構(gòu)建配置和運(yùn)行設(shè)置的步驟
使用 Qt Creator 集成開發(fā)環(huán)境構(gòu)建和運(yùn)行程序是一件非常簡單的事情,一個按鈕或者一個快捷鍵搞定全部,本文主要介紹了Qt creator中項目的構(gòu)建配置和運(yùn)行設(shè)置的步驟,感興趣的小伙伴們可以參考一下2021-11-11
atoi和itoa函數(shù)的實(shí)現(xiàn)方法
本文介紹了,atoi和itoa函數(shù)的實(shí)現(xiàn)方法,需要的朋友可以參考一下2013-03-03
C++圖論核心之最短路徑算法從原理到實(shí)戰(zhàn)
這篇文章主要介紹了C++圖論核心之最短路徑算法,最短路徑問題是指,從在帶權(quán)的有向圖中從某一頂點(diǎn)出發(fā),找到通往另一頂點(diǎn)的最短路徑,最短指的是沿路徑各邊的權(quán)值總和最小,需要的朋友可以參考下2026-02-02
C語言中的sizeof操作符用法及和strlen的區(qū)別
這篇文章主要介紹了C語言中的sizeof操作符用法及和strlen的區(qū)別,本文講解了sizeof的定義、sizeof的語法以及使用實(shí)例,最后給出sizeof與strlen的區(qū)別,需要的朋友可以參考下2015-07-07

