新聞中心
不受限制的字符串函數(shù),比如說strcpy、strcmp等等,我們最常用的字符串函數(shù)都是不受限制的,只是通過尋找字符串參數(shù)結(jié)尾的NULL字節(jié)來判斷它的長度。那么什么是受限制的字符串函數(shù)呢?通過下面的例子我們來一起詳細(xì)了解一下
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供融安網(wǎng)站建設(shè)、融安做網(wǎng)站、融安網(wǎng)站設(shè)計(jì)、融安網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、融安企業(yè)網(wǎng)站模板建站服務(wù),10余年融安做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
strcpy:
原型:char*strcpy(char*strDestination,constchar*strSource );
這個(gè)函數(shù)把參數(shù)src字符串復(fù)制到dest參數(shù)中,在使用這個(gè)函數(shù)時(shí)需要注意,首先,必須保證目標(biāo)字符數(shù)組的空間足以容納需要復(fù)制的字符串,為什么呢?如果字符串比數(shù)組長,多余的字符仍然會(huì)被復(fù)制,這就導(dǎo)致它們會(huì)覆蓋原先存儲(chǔ)在數(shù)組后面的內(nèi)存空間的值。其次,目標(biāo)參數(shù)應(yīng)該是可被修改的,所以它必須是個(gè)字符數(shù)組或者是一個(gè)指向動(dòng)態(tài)分配內(nèi)存的數(shù)組的指針。
1.strcpy模擬實(shí)現(xiàn):
char *my_strcpy(char *dest, const char *src) { char *ret = dest; assert(src != NULL); assert(dest != NULL); while (*dest++ = *src++) { ; } return ret; }
strncpy: 把src所指向的字符串中以src地址開始的前n個(gè)字節(jié)復(fù)制到dest所指的數(shù)組中,并返回dest。
上面是不受限制的字符串函數(shù),那么為什么會(huì)有strncpy這樣一類受限制的字符串函數(shù)呢?
就拿這兩個(gè)函數(shù)來說,strcpy只是復(fù)制字符串,但不限制復(fù)制的數(shù)量,很容易造成緩沖溢出。strncpy要安全一些。strncpy能夠選擇一段字符輸出,strcpy則不能。
下面是strncpy模擬實(shí)現(xiàn):
char *my_strncpy(char *dest, const char *src, int n) { char *ret = dest; assert(dest); assert(src); while (n--) { *dest++ = *src++; } *dest = '\0'; return ret; }
2.將兩個(gè)字符串連接,我們可以使用strcat函數(shù)
函數(shù)原型:
char *strcat( char *strDestination, const char *strSource );
功能:
把src所指字符串添加到dest結(jié)尾處(覆蓋dest結(jié)尾處的'\0')。
說明:
src和dest所指內(nèi)存區(qū)域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針。
char *my_strcat(char *dest, const char *src) { char *ret = dest; assert(src != NULL); assert(dest != NULL); while (*dest) { dest++; } while (*dest++ = *src++) { ; } return ret; }
strncat:
功能
把src所指字符串的前n個(gè)字符添加到dest所指字符串的結(jié)尾處,并覆蓋dest所指字符串結(jié)尾的'\0',從而實(shí)現(xiàn)字符串的連接。
說明
src和dest所指內(nèi)存區(qū)域不可以重疊,并且dest必須有足夠的空間來容納src的字符串。
返回值
返回指向dest的指針。
char *my_strncat(char *dest, const char *src, int len) { char *ret = dest; assert(dest); assert(src); while (*dest) { dest++; } while (len--) { *dest = *src; dest++; src++; } *dest = '\0'; return ret; }
3.strcmp函數(shù):比較兩個(gè)字符串。
有一個(gè)需要注意的地方是
當(dāng)s1 當(dāng)s1=s2時(shí),返回值= 0; 當(dāng)s1>s2時(shí),返回正數(shù)。 即:兩個(gè)字符串自左向右逐個(gè)字符相比(按ASCII值大小相比較),直到出現(xiàn)不同的字符或遇'\0'為止。 有的人以為返回值是1和-1,分別代表大于和小于,如果你也這樣想,那就錯(cuò)了。ANSI標(biāo)準(zhǔn)規(guī)定,返回值為正數(shù),負(fù)數(shù),0 。而確切數(shù)值是依賴不同的C實(shí)現(xiàn)的。 strncmp函數(shù)原型: int strncmp ( const char * str1, const char * str2, size_t n ); 參數(shù)str1, str2 為需要比較的兩個(gè)字符串,n為要比較的字符的數(shù)目。 字符串大小的比較是以ASCII 碼表上的順序來決定,此順序亦為字符的值。strncmp()首先將s1 第一個(gè)字符值減去s2 第一個(gè)字符值,若差值為0 則再繼續(xù)比較下個(gè)字符,直到字符結(jié)束標(biāo)志'\0',若差值不為0,則將差值返回。例如字符串"Ac"和"ba"比較則會(huì)返回字符"A"(65)和'b'(98)的差值(-33)。注意:要比較的字符包括字符串結(jié)束標(biāo)志'\0',而且一旦遇到'\0'就結(jié)束比較,無論n是多少,不再繼續(xù)比較后邊的字符。 strncmp函數(shù)模擬實(shí)現(xiàn): 4.為了在字符串中查找一個(gè)子串,我們可以使用strstr函數(shù) 函數(shù)原型: char*strstr(constchar*string,constchar*strCharSet ); 這個(gè)函數(shù)在s1中查找整個(gè)s2第一次出現(xiàn)的起始位置,并返回一個(gè)指向該位置的指針。如果s2沒有完整地出現(xiàn)在s1的任何地方,函數(shù)將返回一個(gè)NULL指針。如果第二個(gè)參數(shù)是一個(gè)空字符串,函數(shù)就返回s1。 strrstr: 標(biāo)準(zhǔn)庫中并不存在這樣的函數(shù),當(dāng)然,如果需要,也可以很容易實(shí)現(xiàn) strrstr函數(shù)在字符串s1中查找s2最后出現(xiàn)的位置 5.在一個(gè)字符串中查找一個(gè)特定字符最容易的方法是使用strchr函數(shù) 這個(gè)函數(shù)比較簡單,下面是模擬實(shí)現(xiàn): strrchr: strrchr() 函數(shù)查找字符在指定字符串中從后面開始的第一次出現(xiàn)的位置,如果成功,則返回從該位置到字符串結(jié)尾的所有字符,如果失敗,則返回 false。與之相對(duì)應(yīng)的是strstr()函數(shù),它查找字符串中首次出現(xiàn)指定字符的位置。 函數(shù)原型: char*strrchr(constchar*string,intc ); 當(dāng)然,關(guān)于str這樣的函數(shù)還有很多,這里模擬實(shí)現(xiàn)了一些經(jīng)常用的函數(shù),希望互相借鑒幫助。int my_strcmp(const char *str1, const char *str2)
{
assert(str1);
assert(str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 - *str2 > 0)
return -1;
else
return 1;
}
int my_strncmp(const char *dest, const char*src, int count)
{
assert(dest);
assert(src);
while (count>0 && (*dest == *src))
{
if (*dest == '\0')
return 0;
dest++;
src++;
count--;
}
return *dest - *src;
}
char *my_strstr(const char *str, const char *substr)
{
assert(str != NULL);
assert(substr != NULL);
char *s1 = (char *)str;
char *s2 = (char *)substr;
char *start = (char *)str;
while (*start)
{
s1 = start;
while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
return start;
s2 = (char *)substr;
start++;
}
return NULL;
}
char* my_strrstr(char const *s1, char const *s2)
{
char *last = NULL; //將指針初始化為已經(jīng)找到的前一次匹配位置
char *current = NULL;
assert(s1);
assert(s2);
if (*s2 ) //只有在第二個(gè)字符串不為空時(shí)才進(jìn)行查找
{
current = (char *)strstr(s1, s2);//s2在s1中第一次出現(xiàn)的位置
while (current != NULL)
{
//每次找到字符串時(shí),讓指針指向它的起始位置,然后查找該字符串下一個(gè)匹配位置
last = current;
current = (char*)strstr(last + 1, s2);
}
}
return last;
}
#include
char *my_strrchr(char *str, char ch)
{
char *ptr = NULL;
assert(str);
while (*str)
{
if (*str == ch)
ptr = str;
str++;
}
if (ptr != 0)
return ptr;
return 0;
}
int main()
{
char ch = 0;
char *ret = NULL;
char *arr = "feabadc";
printf("請(qǐng)輸入一個(gè)你要查找的字符:");
scanf_s("%c", &ch);
ret = my_strrchr(arr, ch);
printf("%s\n", *ret);
system("pause");
return 0;
}
網(wǎng)頁名稱:關(guān)于str家族
URL標(biāo)題:http://www.dlmjj.cn/article/pgiosg.html