字符串和内存函数的模拟实现

本文重点:

1.求字符串长度:strlen
2.长度不受限制的字符串函数: strcpy , strcat , syrcmp
3.长度受限制的字符串函数:strncpy , strncat , strncmp
4.字符串查找:strstr , strtok
5.错误信息报告:strerror
6.内存操作函数:memcpy , memmove , memset , memcmp

在C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。

一.关于字符串函数的分类和模拟实现:

1.strlen(求字符串长度)

size_t  strlen ( const char * str );

//注意其中size_t表示返回值是一个无符号的长整型;
//其中const 指其指向的内容不能进行修改;

注意:

字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 \0’)。 参数指向的字符串必须要以 ‘\0’ 结束。
注意函数的返回值为size_t,是无符号的( 易错 )

关于strlen函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
size_t strlen(const char* str){
	assert(str!=NULL);
	size_t count=0;
	while(str[i]!='\0'){
		count++;
	}
	return count;
}
int main(){
	char str[]="hehe";
	char* p=str;
	if(p!='\0'){
		printf("%lu\n",strlen(p));
	}
	system("pause");
	return 0;
}

2.strcpy(字符串拷贝)
char* strcpy(char * destination, const char * source );
注意:字符串只能使用 = 初始化,不能使用 = 赋值;

实现:
(1)会将源字符串中的 ‘\0’ 拷贝到目标空间。
(2)目标空间必须足够大,以确保能存放源字符串。
(3)目标空间必须可变。

关于strcpy函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* strcpy(char *dest,char* src){
	assert(dest!=NULL);
	assert(src!=NULL);
	for(int i=0;dest[i]!='\0';i++){
		dest[i]=src[i];
	}
	dest[i]='\0';
	return 0;
}
int main(){
	char dest[]="hehehe";
	strcpy(dest,"haha");
	printf("%s\n",dest);
	system("pause");
	return 0;
}
3.strcat(字符串拼接)
char * strcat ( char * destination, const char * source );

源字符串必须以 ‘\0’ 结束;
目标空间必须有足够的大,能容纳下源字符串的内容;
目标空间必须可修改;

关于strcat函数的模拟实现:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* strcat(char* dest,char* src){
	assert(dest!=NUL);
	assert(src!=NULL);
	for(int i=0;dest[i]!='\0';i++);
	for(int j=0;src[j]!='\0';i++,j++){
		dest[i]=src[j];
	}
	dest[i]='\0';
	return dest;
}

int main(){
	char dest[1024]="hehehe";
	strcat(dest,"hahaha");
	printf("%s\n",dest);
	system("pause");
	return 0;
}

4.strcmp(字符串比较)
int strcmp ( const char * str1, const char * str2 ); 

标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字;

关于strcmp函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int strcmp(const char* str1,const char* str2){
	assert(str1!=NULL);
	assert(str2!=NULL);
	while(*str1!='\0' && *str2!='\0'){
		if(*str1>*str2){
			return 1;
		}
		if(*str1<str2){
			return -1;
		}
		else{
		++str1;
		++str2;
		}
	}
	if(*str1=='\0' && *str2!='\0'){
		return -1;
	}
	else if(*str1!='\0' && *str2=='\0'){
		return 1;
	}
	else if(*str1=='\0' && *str2!='\0'){
	 	return 0;
	 }
}

int main(){
	char str1[]="hahahaha";
	char str2[]="hehehe";
	int ret=strcmp(str1,str2);
	if(ret<0){
		printf("小于\n");
	}else if(ret==0){
		printf("等于\n");
	}else if(ret>0){
		printf("大于\n");
	}
	system("pause");
	return 0;
}
		
5.strstr(字符串查找)
char * strstr ( const char *str1, const char *str2 );
关于strstr函数的模拟实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* strstr(const char* str1,const char* str2){
	assert(str1!=NULL);
	assert(str2!=NULL);
	if(*str1=='\0' && *str2=='\0'){
		return NULL;
	}
	const char* black_ptr=str1;
	while(*black_ptr!='\0'){
		const char* sub_ptr=str2;
		const char*red_ptr=black_ptr;
		while ( * red_ptr !='\0' && * sub_ptr!='\0'  && (*red_ptr==*sub_ptr)) {
              ++sub_ptr;
              ++red_ptr;
        }
        if (* sub_ptr=='\0') {
       //说明已经找到了子字符串;
        	return black_ptr;
        }
        ++black_ptr;
   }
   return NULL;
}
		

二.关于内存函数介绍及模拟实现:

1.memcpy(字符串拷贝函数)
void * memcpy ( void * destination, const void * source, size_t num );1)这个函数在遇到 '\0' 的时候并不会停下来。
(2)如果source和destination有任何的重叠,复制的结果都是未定义的。

功能:
由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。

关于memcpy函数的模拟实现:
#include<stdlib.h>
#include<string.h>
#include<assert.h>
void * Memcpy (void* dest ,const void* src, size_t num) {
	assert (dest!= NULL);
    assert (src!=NULL);
    char *pdest= (char* ) dest;
    char * psrc=(char* )src;
    for (size_t=i; i<num;++i) {
         pdest[i]=psrc[i];
    }
    return dest;
 }
int main( ) {
   	int arr1[4] ={1,2,3,4};
   	int arr2[4] ={0};
   	memcpy (arr2, arr1, sizeof(arr1));
   	for ( int i=0; i<4; ++i) {
      	printf ( "%d\n", arr2[i]);
    }
    system("pause");
   	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值