C语言:字符函数和字符串函数 strlen strcpy strcat strcmp strstr memcmp memove memcmp

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

#include <stdio.h>
int My_strlen(const char *ch)     //加const是为了不要让其他的条件改变ch的值
{
	int count = 0;             //定义一个计数器count
	while((*ch++)!='\0')       //只要ch数组里面的字符串不是\0则计数器就加1
	{
		count++;
	}
	return count;            //将计数器的值返回
}
int main()
{
	char ch[]="abcdef";
	int len = My_strlen(ch);
	printf("%d\n",len);
	return 0;
}

长度不受限制的字符串函数
strcpy

char  *strcpy(char  * destination,  const  char * source);
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
void My_strcpy(char *dest,const char *src)             //加const的目的是为了保证src所指向的字符串不被外界因素改变
{
	while((*dest++=*src++)&&*src!='\0')           //将src里的字符复制给dest
		;
	*dest++ =  '\0';                              //上面的复制并没有将\0复制给dest,所以这里要加上
}
int main()
{
	char arr[]="abcdef";
	char aim[7];
	My_strcpy(aim,arr);
	printf("%s\n",aim);
	return 0;
}

strcat(字符串的追加)
char * strcat(char destnation, const char source);
源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

char* my_strcat(char* dest, char* src)
{
    char *cp = dest;
    assert(src && dest);
    while (*dest != '\0')
    {
        dest++;
    }
    while (*dest++ = *src++)
    {
        ;
    }
    return cp;
}

int main()
{
    char str[32] = "abcd";
    char buf[32] = "efgh";
    printf("%s\n", my_strcat(str, buf));
        system("pause");
    return 0;
}

strcmp(字符串的比较)
int strcmp (const char* str1, char * str2);
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

#include<stdio.h>
#include<assert.h> 

int my_strcmp(const char* arr1,const char* arr2)
{
	int ret=0;
	assert(arr1);
	assert(arr2);
	while( !(ret = *(unsigned char*) arr1 - *(unsigned char* ) arr2 )         //  整形提升
		&& *arr1)  //两个条件同时满足才执行循环内容
	{
		arr2++;
		arr1++;	
	}
	if(ret<0)
		return -1;
	else if(ret>0)
		return 1;
	else
	{
		;   //do nothing 
	}
	return 0;
}

int main()
{
	char arr1[]="123abcd";
	char arr2[]="123Abcd";
	char arr3[]="123Abcd";
	printf("%d\n",my_strcmp(arr1,arr2));
	printf("%d\n",my_strcmp(arr2,arr3));
    printf("%d\n",my_strcmp(arr3,arr1));
	return 0;
}

strstr(判断是否是子串)
char strstr(const char ,const char*)

char* my_strstr(const char*str1, const char* str2)
{
	assert(str1 != NULL);
	assert(str2 != NULL);
	//下面这个if语句判断str2是不是空的,
	//如果是空则直接返回str1
	if (*str2 == '\0')
	{
		return (char*)str1;
	}

	while (*str1 != '\0')//当str1没到‘\0’时,执行下面,否则返回NULL
	{
		const char* p1 = str1;//创建新指针指向str1
		const char* p2 = str2;//同上
		while (*p2 != '\0')
		{
			if (*p1 != *p2)
			{
				break;
			}
			else
			{
				p1++;
				p2++;
			}
		}
		if ('\0' == *p2)
		{
			return (char*)str1;
		}
		++str1;
	}
	return NULL;
}
int main()
{
	char *str1 = "hello world";
	char *str2 = "llo";
	printf("%s", strstr(str1, str2));

	system("pause");
	return 0;
}

memcpy
void *memcpy(void * destnation ,const void * source,size_t num);
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 ‘\0’ 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的

void* my_memcpy(void* dest, const void* src, size_t n)
{
	assert(dest);
	assert(src);
	char* pdest = (char*)dest;
	const char* psrc = (const char*)src;
	while (n--)
	{
		*pdest++ = *psrc++;
	}
	return dest;
}

memove
int memcmp(const void * ptr1,
const void *ptr2,
size_t num)

和memcpy的差别就是memove函数处理的源内存块和目标内存块是可以重叠的
如果源空间和目标空间出现重叠,就得使用memove函数处理

void *MyMemmove(void * dest, const void * src, size_t num)
     //和memcpy最大的不同就是,它是内存移动,反向拷贝,不是从头开始
 {
    void *ret = dest;
    char *str1 = (char*)dest;
    char *str2 = (char*)src;
    if(str1>str2)
    //只有当前面的位置比后面的位置高,才会反向拷贝,因为会有覆盖现象
    {
        while(num--)
        {
            *(str1+num) = *(str2+num);//反向赋值
        }
    }
    else
    {
        while(num--)
        {
            *str1++ = *str2++;
        }
    }
    return ret;
 }   

memcmp
int memcmp(const void * ptr1,
const void * ptr2,
size_t num);

比较从ptr1和ptr2指针开始的num个字节

int my_memcmp2(const void *p1, const void *p2, size_t count)//方法2
{
    assert(p1);
    assert(p2);
    int ret = 0;
    char *dest = (char *)p1;
    char *src = (char*)p2;
    while (count && (!(ret = (*dest - *src))))
    {
        dest++;
        src++;
        count--;
    }
    if (ret > 0)
    {
        return 1;
    }
    else if (ret < 0)
    {
        return -1;
    }
    return 0;
 
}
 
int main()
{
    int arr1[] = {1,2,3,4,5,6};
    int arr2[] = {1,2,3,1000000,5,6};//清楚内存是怎样放置的
    int ret = my_memcmp2(arr1, arr2, 16);
    printf("%d", ret);
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值