C語(yǔ)言模擬實(shí)現(xiàn)字符串操作函數(shù)
前言
在編寫(xiě)程序過(guò)程中,我們經(jīng)常使用到一些字符串函數(shù),例如求字符串長(zhǎng)度,拷貝字符串……,這些函數(shù)都在C標(biāo)準(zhǔn)庫(kù)中存在,我們可以直接使用。但我們還需要掌握這些函數(shù)的實(shí)現(xiàn)方法,今天來(lái)看看一些常用的字符串操作函數(shù)的實(shí)現(xiàn)方法。
帶長(zhǎng)度參數(shù)的函數(shù)
1. strlen
strlen是用來(lái)求字符串長(zhǎng)度的函數(shù),字符串長(zhǎng)度就是字符串中包含的字符的個(gè)數(shù),但是不包含字符串結(jié)尾的 ‘\0’ 實(shí)現(xiàn)strlen有三種方法:
(1)定義一個(gè)計(jì)數(shù)器
size_t mystrlen(const char* str) { size_t count = 0; while (*str != '\0')
{
count++;
str++;
} return count;
}
(2)遞歸版本
size_t my_strlen(const char *str) { if (*str == '\0') return 0; else return my_strlen(str + 1) + 1;
}
(3)利用指針 - 指針
size_t mystrlen(const char* str) { const char* end = str; while (*end++); return end - str - 1;
}
2.strcpy
用于復(fù)制字符串的函數(shù)是strcpy,它的原型如下:
char* strcpy ( char* dest, const char* src );
使用這個(gè)函數(shù)時(shí),要注意幾點(diǎn) (1)目標(biāo)字符數(shù)組的空間必須足夠大,足以容納需要復(fù)制的字符串 (2)目標(biāo)字符數(shù)組要可以被修改 (3)被復(fù)制的字符串要可以找到’\ 0’
char *mystrcpy(char *dest, const char *src) { char *res = dest;
assert(dest);
assert(src); while (*dest++ = *src++) ;//注意這里是一個(gè)等號(hào) return res;
}
3.strcat
strcat函數(shù)是可以把一個(gè)字符串添加(連接)到另一個(gè)字符串的后面。strcat函數(shù)要求dest參數(shù)原先已經(jīng)包含了一個(gè)字符串(可以是空字符串)。它找到這個(gè)字符串的末尾,并把src字符串的一份拷貝添加到這個(gè)位置。
char *mystrcat(char *dest, const char *src) { char *res = dest;
assert(dest);
assert(src); while (*dest != '\0')
dest++; while (*dest++ = *src); //這里同樣也是一個(gè)等號(hào) return res;
}
4.strcmp
strcmp用于比較兩個(gè)字符串,及對(duì)兩個(gè)字符串對(duì)應(yīng)的字符逐個(gè)進(jìn)行比較,直到發(fā)現(xiàn)不匹配。那個(gè)最先不匹配的字符中較“小”的那個(gè)字符所在的字符串被認(rèn)為“小于”另外一個(gè)字符串。如果其中一個(gè)字符串是另外一個(gè)字符串的前面一部分,那么它也被認(rèn)為“小于”另外一個(gè)字符串,因?yàn)樗摹痋0’出現(xiàn)的更早。
int my_strcmp(const char* src1, const char* src2) { while (*src1 == *src2)
{ if (*src1 == '\0') return 0;
src1 ++;
src2 ++;
} return *src1 - *src2;
}
5.strstr
為了在一個(gè)字符串中查找一個(gè)子串,可以使用strstr函數(shù),該函數(shù)是在s1中查找整個(gè)s2第1次出現(xiàn)的起始位置,并返回一個(gè)指向該位置的指針。如果s2并沒(méi)有出現(xiàn)在s1的任何地方,函數(shù)將返回一個(gè)NULL指針。如果第二個(gè)函數(shù)是一個(gè)空字符串,函數(shù)就返回s1。
char* my_strstr(char* s1, const char* s2) { char* p = s1; const char* q = s2; char* cur = NULL;
assert(s1);
assert(s2); if (*s2 == '\0') return s1; while (*p != '\0')
{
cur = p; while ((*p != '\0') && (*q != '\0') && (*p == *q))
{
p++;
q++;
} if (*q == '\0') return cur;
p = cur + 1;
q = s2;
} return NULL;
}
6.strchr
strchr是用來(lái)查找一個(gè)特定的字符,在字符串str中查找字符ch第一次出現(xiàn)的位置,找到后函數(shù)返回一個(gè)指向該位置的指針。如果該字符并不存在于字符串中,函數(shù)就返回一個(gè)NULL指針
char* my_strchr(const char* str, char ch) { const char* tmp = str; while (*tmp)
{ if (*tmp == ch) return tmp;
tmp++;
} return NULL;
}
7.strrchr
與strchr類似的查找函數(shù)還有一個(gè)是strrchr,它和strchr的不同之處在于,該函數(shù)返回的是一個(gè)指向字符串中該字符最后一次出現(xiàn)的位置
char* my_strrchr(const char* str, int ch) { char* pos = 0;
assert(str); while (*str)
{ if (*str == ch)
{
pos = str;
}
str++;
} if (pos != 0)
{ return pos;
} else return NULL;
}
長(zhǎng)度受限制的字符串函數(shù)
標(biāo)準(zhǔn)庫(kù)中還包含一些函數(shù),它們以一種不同的方式去處理字符串。這些函數(shù)接受一個(gè)顯示的長(zhǎng)度參數(shù),用于限定進(jìn)行復(fù)制或比較的字符數(shù)。
1.strncpy
和strcpy一樣,strncpy()函數(shù)把源字符串的字符復(fù)制到目標(biāo)空間,但是,它總是正好向dest中拷貝len個(gè)字符,如果strlen的(src)的值小于len,dest數(shù)組就用額外的’\0’填充到len字節(jié)長(zhǎng)度。如果strlen的(src)的值大于或等于len,那么只有l(wèi)en個(gè)字符被復(fù)制到目標(biāo)寄存器中。
char* my_strncpy(char* dest, const char* src, size_t len) { char* res = dest;
assert(dest);
assert(src); while (len--)
{
*res++ = *src++;
} if (*(res) != '\0')
*res = '\0'; return dest;
}
2.strncat
strncat函數(shù),它從src中最多復(fù)制的len個(gè)字符到目標(biāo)數(shù)組的后面。
char* my_strncat(char* dest, const char* src, size_t len) { char* res = dest;
assert(dest);
assert(src); while (*dest != '\0')
dest++; while (len--)
{
*dest = *src;
dest++;
src++;
} return res;
}
3.strncmp
strncmp也用于比較兩個(gè)字符串,但它最多比較len個(gè)字節(jié)。如果兩個(gè)字符串在第len個(gè)字符之前存在不相等的字符,這個(gè)函數(shù)就像的strcmp一樣停止比較,返回結(jié)果。如果兩個(gè)字符串的前l(fā)en個(gè)字符相等,函數(shù)就返回零。
int my_strncmp(const char* s1, const char* s2, size_t len) {
assert(s1);
assert(s2); while (len--)
{ if (*s1 == *s2)
{
s1++;
s2++;
} else return *s1 - *s2;
} return 0;
}
標(biāo)準(zhǔn)庫(kù)里的字符串函數(shù)還有很多,今天就先介紹到這里。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!