一篇文章教你用C語(yǔ)言模擬實(shí)現(xiàn)字符串函數(shù)
前言
編程過(guò)程中經(jīng)常會(huì)使用到一些字符串函數(shù),這些字符串函數(shù)都在C語(yǔ)言標(biāo)準(zhǔn)庫(kù)中,我們可以直接使用。但我們也要了解一下它們是如何實(shí)現(xiàn)的。
模擬
1.strlen 函數(shù)
strlen函數(shù)是用來(lái)求字符串長(zhǎng)度的。官方給出的解釋如圖

返回值類型是無(wú)符號(hào)整型,參數(shù)類型是char*,遇見(jiàn)\0停止。
strlen的模擬實(shí)現(xiàn)有三種方法,1、count計(jì)數(shù)。2、遞歸。3、指針減指針。
count計(jì)數(shù)
#include <stdio.h>
int my_strlen(const char* str) {
int count = 0;
while (*str++) {
count++;
}
return count;
}
int main() {
char str[] = "abcdefg";
int len = my_strlen(str);
printf("%d", len);
return 0;
}
遞歸
#include <stdio.h>
int my_strlen( const char* str) {
if (*str == '\0') {
return 0;
}
else {
return my_strlen(++str) + 1;
}
}
int main() {
char str[] = "abcdefg";
int len = my_strlen(str);
printf("%d", len);
return 0;
}
指針減指針
#include <stdio.h>
int my_strlen(const char* str) {
char* p = str;
while (*p) {
p++;
}
return p - str;
}
int main() {
char str[] = "abcdefg";
int len=my_strlen(str);
printf("%d", len);
return 0;
}
2.strcpy 函數(shù)
strcpy函數(shù)是字符串拷貝函數(shù)。就是把源地址字符串拷貝到目的地址去。源地址字符串必須有\(zhòng)0。目的地址必須足夠大。源地址字符串的\0也會(huì)拷貝過(guò)去,返回目的地址的地址。
官方解釋如圖

模擬實(shí)現(xiàn)
#include <stdio.h>
char* my_strcpy(char* dest,const char* sour) {
char* p=dest;
while (*dest++ = *sour++) {
;
}
return p;
}
int main() {
char sur[] = "abcdefg";
char dest[10] = { 0 };
printf("%s", my_strcpy(dest,sur));
return 0;
}
3.strcat 函數(shù)
strcat函數(shù)是字符串追加函數(shù)。就是把源地址字符串追加到目的地址后邊。要注意的是當(dāng)遇見(jiàn)源地址的\0時(shí)停止,目的地址必須可修改,且足夠大。strcat函數(shù)不能用于追加字符串自己,會(huì)越界,根本停不下來(lái)。
官方解釋如圖

模擬實(shí)現(xiàn)
#include <stdio.h>
char* my_strcat(char* str2,const char* str1) {
char* p = str2;
while (*str2++){
;
}
str2--;
while (*str2++ = *str1++) {
;
}
return p;
}
int main() {
char str1[] = "abcdefg";
char str2[20]="abc";
printf("%s", my_strcat(str2, str1));
return 0;
}
4.strcmp函數(shù)
strcmp函數(shù)是字符串比較函數(shù),如果str1比str2大就返回正值,str1比str2小返回負(fù)值。str1=str2比較下一對(duì)字符。只要有一個(gè)遇見(jiàn)\0就停止。
官方解釋如圖

模擬實(shí)現(xiàn)
#include <stdio.h>
int my_strcmp( const char* str1,const char* str2) {
while (*str1++-*str2++==0 && *str1!='\0' && str2!='\0') {
;
}
return *--str1 - *--str2;
}
int main() {
char str1[] = "abcdefg";
char str2[] = "bbcdef";
int a=my_strcmp(str1,str2);
printf("%d", a);
return 0;
}
5.strncpy函數(shù)
strncpy函數(shù)是長(zhǎng)度受限制的字符串拷貝函數(shù),可以指定拷貝多少給字節(jié),當(dāng)給定的字節(jié)數(shù)大于要拷貝的字符串時(shí),不夠的用\0補(bǔ)充。
官方解釋

模擬實(shí)現(xiàn)
#include <stdio.h>
char* my_strncpy(char* dest,const char* sour,int num) {
char* p = dest;
while (num--) {
if (*sour != '\0') {
*dest++ = *sour++;
}
else {
*dest++ = '\0';
}
}
return p;
}
int main() {
char sur[] = "abcdefg";
char dest[10] = { 0 };
printf("%s", my_strncpy(dest, sur,10));
return 0;
}
6.strncat函數(shù)
strncat函數(shù),需要注意的一點(diǎn)是,字符串追加完成后目的地址斜杠零是追加完后自己補(bǔ)充的。所以它可以實(shí)現(xiàn)自己給自己 追加。
官方解釋

模擬實(shí)現(xiàn)
#include <stdio.h>
char* my_strncat(char* str2,const char* str1,size_t num) {
char* p = str2;
while (*str2++){
;
}
str2--;
while (num--) {
if (*str1 != '\0') {
*str2++ = *str1++;
}
}
*str2 = '\0';
return p;
}
int main() {
char str1[] = "abcdefg";
char str2[20]="abc";
printf("%s", my_strncat(str2, str1,6));
return 0;
}
7.strncmp函數(shù)
strncmp函數(shù),比較字符串,和strcmp類似只是可以確定比較前幾個(gè)字符。
官方解釋

模擬實(shí)現(xiàn)
#include <stdio.h>
int my_strncmp( const char* str1,const char* str2,size_t num){
while (num--&& *str1++-*str2++==0 && *str1!='\0'&& str2!='\0') {
;
}
return (*--str1 - *--str2);
}
int main() {
char str1[] = "abcdefg";
char str2[] = "bbcdef";
int a=my_strncmp(str1,str2,5);
printf("%d", a);
return 0;
}
8.strstr函數(shù)
strstr函數(shù)就是在一個(gè)字符串里找子字符串。
官方解釋

模擬實(shí)現(xiàn)
#include <stdio.h>
const char* my_strstr(const char* str1, const char* str2) {
while (*str1) {
const char* p1 = str1;
const char* p2 = str2;
while (*p1++ == *p2++) {
;
}
if (*--p2 == '\0') {
break;
}
else {
str1++;
}
}
return str1;
}
int main() {
char str1[] = "abbbcdefg";
char str2[] = "bcde";
int len = strlen(str2);
const char* p = my_strstr(str1, str2);
while (len--) {
printf("%c", *p++);
}
return 0;
}
9.strtok函數(shù)
strtok函數(shù)是字符串切割函數(shù),用的比較少也比較難懂。用的是時(shí)候要給一個(gè)用做分隔符的字符集合。strtok函數(shù)找到分隔符后將其置為0.返回一個(gè)指向該標(biāo)記的指針。如果第一個(gè)參數(shù)不為空則strtok找到第一個(gè)分隔符將其置零并記錄該處地址,第二次調(diào)用strtok則傳一個(gè)NULL則strtok會(huì)從前一個(gè)'\0‘處往后找下一個(gè)分隔符。
官方解釋

模擬實(shí)現(xiàn)
#include <string.h>
#include <stdio.h>
char* my_strtok(char* str, char* demion)
{
static char* p_last = NULL;
if (str == NULL && (str = p_last) == NULL)
{
return NULL;
}
char* s = str;
char* t = NULL;
while (*s != '\0')
{
t = demion;
while (*t != '\0')
{
if (*s == *t)
{
p_last = s + 1;
if (s - str == NULL)
{
str = p_last;
break;
}
*s = '\0';
return str;
}
t++;
}
s++;
}
return NULL;
}
int main(void)
{
char str[] = "liusen,lin,lll";
char* result = NULL;
result = my_strtok(str, ",");
printf("%s\n", result);
result = my_strtok(NULL, ",");
printf("%s\n", result);
return 0;
}
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語(yǔ)言算法練習(xí)之折半查找的實(shí)現(xiàn)
二分查找法(也叫折半查找)其本質(zhì)是分治算法的一種。這篇文章主要介紹了如何利用C語(yǔ)言實(shí)現(xiàn)折半查找,感興趣的小伙伴可以學(xué)習(xí)一下2022-05-05
C語(yǔ)言示例講解do?while循環(huán)語(yǔ)句的用法
在不少實(shí)際問(wèn)題中有許多具有規(guī)律性的重復(fù)操作,因此在程序中就需要重復(fù)執(zhí)行某些語(yǔ)句。一組被重復(fù)執(zhí)行的語(yǔ)句稱之為循環(huán)體,能否繼續(xù)重復(fù),決定循環(huán)的終止條件2022-06-06
c++動(dòng)態(tài)內(nèi)存管理與智能指針的相關(guān)知識(shí)點(diǎn)
為了更容易同時(shí)也更安全地使用動(dòng)態(tài)內(nèi)存,新的標(biāo)準(zhǔn)庫(kù)提供了兩種智能指針(smart pointer)類型來(lái)管理對(duì)象,下面這篇文章主要給大家介紹了關(guān)于c++動(dòng)態(tài)內(nèi)存管理與智能指針的相關(guān)知識(shí)點(diǎn),需要的朋友可以參考下2022-03-03

