字符串函数与内存函数解析与模拟实现(重要内容)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言:

本章学习字符串与内存相关函数。

1.strlen

功能: strlen 函数只适用于字符串 不能用于其他数据类型。strlen函数可以计算出字符串的长度。

头文件: string.h

1.使用strlen函数

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[] = "abcdef";
    int len1 = strlen(arr);
    char arr2[] = {'a','b','c','d'};
    int len2 = strlen(arr);
    printf("%d %d ",len1,len2);
}

1.21.1

len1 算出的是6(也就是字符串arr1的长度),而len2算出的是13。为什么呢?

因为strlen函数是通过字符串中的"\0"来计算的,直到遇到字符串的"\0"才会停止计算

2.模拟实现strlen函数

int my_strlen(const char* str)    //使用指针接收数组的首元素地址
{
	assert(str);                  //assert函数判断str,反正出现野指针的情况
	int count = 0;                //计数变量代表长度
	while (*str)                  //*str如果等于“\0",则其assci码值为0,0为假跳出循环
	{                             
		count++;            
		str++;                    //每计数完成一次,指针指向下一个元素的地址
	}
	return count;                 //返回字符串长度,int类型接收
}

2. strcpy

功能:将一个字符串内容拷贝到另一个字符类型的数组中去。

头文件: string.h

注意:

源字符串必须以’\0’结束。

会将源字符串中的’\0’拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。

1.使用strcpy函数

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[] = "abcdef";
    char arr2[20] = {0};
    strcpy(arr2,arr1);
    printf("%s",arr2);
}

2.模拟实现strcpy

char* my_strcpy(char* dest, const char* src)    
{	
    char* ret = dest;     
	assert(dest && src);  
	while (*dest++ = *src++ )   //循环实现拷贝。
	{
		;    
	}
	return ret;
}

3.strcat

1.使用strcat函数

功能:追加字符串。

头文件:string.h

注意:

源字符串必须以’\0’结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "abcdef";
    char arr2[] = "ghijkmn";
    strcat(arr1,arr2);
    printf("%s",arr1);
}

2.模拟实现strcat

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//1. 目标空间中的\0
	while (*dest)
	{
		dest++;
	}
	//2. 追加内容到目标空间
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

4.strcmp

1.使用strcmp函数

功能:

这个函数开始比较每个字符串的第一个字符。如果它们相等,则继续执行下面的对,直到字符不同或到达一个结束的空字符为止。

头文件:string.h

注意:

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于0的数字

#include<stdio.h>
int main()
{
	//strcmp - 字符串比较
	//比较是对应位置上的字符大小
	char arr1[] = "abcd";
	char arr2[] = "abcf";

	int ret = strcmp(arr1, arr2);

	if (ret<0)
	{
		printf("arr1<arr2");
	}
	else if (ret >0)
	{		printf("arr1>arr2");
	}
    else
	{
        printf("arr1=arr2");
	}
	return 0;
}

可以自己修改arr1与arr2的内容去学习该函数

2.模拟实现strcmp

int my_strcmp(const char* str1, const char*str2)
{
    	assert(str1 && str2);
      while (*str1 == *str2)
	{
	if (*str1 == '\0')
			return 0;
		
		str1++;
		str2++;
	}
	return *str1 - *str2;

	/*if (*str1 > *str2)            第二种 
    return 1;	else		return -1;
    */
}

5.strncpy

1.使用strncpy函数

功能:

将源的第一个num字符复制到目标。如果在复制num字符之前找到源C字符串的结尾(以空字符为标志),则destination将用零填充,直到将num字符写入到destination字符中为止。

头文件:string.h

注意:

拷贝num个字符从源字符串到目标空间。

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "hello\0xxxxxxx";
	char arr2[] = "world";
	printf("%s\n", arr1);
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

2.模拟实现strncpy

char* my_strncpy(char* dest, const char* src,int num)    
{	
    char* ret = dest;     
	assert(dest && src);  
	while(num--)
    {
        *dest = *src;
        dest++;
        src++;
    }
	return ret;
}

6.strncat

1.使用strncat函数

功能: 将源的第一个num字符添加到目标,并加上一个结束的空字符。

头文件:string.h

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "hello\0xxxxxxx";
	char arr2[] = "world";
	printf("%s\n", arr1);
	strncat(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

2.模拟实现strncat

char* my_strncat(char* dest, const char* src,int num)
{
	char* ret = dest;
	assert(dest && src);
	//1. 目标空间中的\0
	while (*dest)
	{
		dest++;
	}
	//2. 追加内容到目标空间
	while (num--)
	{
		*dest = *src;
        dest++;
        src++;
	}
    *dest = '\0';
	return ret;
}

7.strncmp

1.使用strncmp函数

功能:比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcwef";
	char arr2[] = "abcqqqqqq";
	int ret = strncmp(arr1, arr2, 4);
	printf("%d\n", ret);
    return 0;
}

模拟实现strncmp函数

int my_strcmp(const char* str1, const char*str2,int num)
{
    	assert(str1 && str2);
      while (*str1 == *str2)
	{
          num--;
	if (num==0)
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;

8.strstr

1.使用strstr函数

功能:找出字符串中的对应子字符串

返回一个指向str1中首次出现str2的指针,如果str2不是str1的一部分,则返回一个空指针。

头文件:string.h

#include <stdio.h>
#include <string.h>
int main ()
{  
    char str[] ="This is a simple string";  
    char * pch;  pch = strstr (str,"simple");  
    strncpy (pch,"sample",6);  
    puts (str); 
    return 0;
} 

2.模拟实现strstr函数

//模拟实现strstr
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* cur = str1;
	const char* s1 = str1;
	const char* s2 = str2;
	while (*cur != '\0')
	{
		s1 = cur;
		s2 = str2;
		while (*s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)cur;
		cur++;
	}
	return NULL;
}

9.strtok

1.使用strtok函数

功能: 分割字符串(学会使用即可)

解析函数:

char * strtok ( char * str, const char * sep );

1.sep参数是个字符串,定义了用作分隔符的字符集合第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。

2.strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

3.strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。

4.strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

5.如果字符串中不存在更多的标记,则返回NULL指针。

#include <stdio.h>
#include <string.h>

int main()
{
	const char* p = "@.#";
	char arr[] = "zpengwei@yeah.net#hehe";
	char buf[50] = { 0 };// "zpengwei@yeah.net"
	strcpy(buf, arr);
	char* str = NULL;

	for (str = strtok(buf, p); str != NULL; str=strtok(NULL, p))
	{
		printf("%s\n", str);
	}

	char* str = strtok(buf, p);//zpengwei
	printf("%s\n", str);
	str = strtok(NULL, p);//yeah
	printf("%s\n", str);
	str = strtok(NULL, p);//net
	printf("%s\n", str);
	return 0;
}

10.strerror

功能:返回错误码,所对应的错误信息。

char * strerror ( int errnum );

头文件:string.h

与之有关的全局变量:errno 头文件为errno.h

#include <stdio.h>
#include <errno.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		//出错误的原因是什么
		printf("%s\n", strerror(errno));
		return 0;
	}

11.字符分类函数

头文件:ctype.h

图片 1.21.4

12.memcpy

1.使用memcpy函数

void * memcpy ( void * destination, const void * source, size_t num );

函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

这个函数在遇到’\0’的时候并不会停下来。

如果source和destination有任何的重叠,复制的结果都是未定义的。

int main()
{
      int arr3[] = { 1,2,3,4,5,6,7,8,9,10 };
	  int arr4[5] = { 0 };
       memcpy(arr4, arr3+5, 5*sizeof(arr3[0]));
       int i = 0;
         for (i = 0; i < 5; i++)
       {
     	printf("%d\n", arr4[i]);
       }
	return 0;
}

2.模拟实现momcpy

void* my_memcpy(void* dest, const void*src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
    
	while (num--) 
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}

	return ret;
}

13.memmove

1.使用mommove函数

void * memmove ( void * destination, const void * source, size_t num );

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用memmove函数处理。

#include <stdio.h>
#include <string.h>
int main ()
{  
    char str[] = "memmove can be very useful......";  
    memmove (str+20,str+15,11);
    puts (str);
    return 0;
}

2.模拟实现mommove

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	
	if (dest < src)
	{
        //前->后
		while (num--)
		{
		*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
    }
	else
	{
        //后->前
        while (num--)
		{
		*((char*)dest+num) = *((char*)src + num);
		}
	}
	return ret;
}

14.momcmp

1.使用momcmp函数

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

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

返回值:

第一个字节大于第二个字节,则返回大于0的数字

第一个字节等于第二个字节,则返回0

第一个字节小于第二个字节,则返回小于0的数字

#include <stdio.h>
#include <string.h>
int main ()
{  
    char buffer1[] = "DWgaOtP12df0";  
    char buffer2[] = "DWGAOTP12DF0";   
    int n;  
    n=memcmp ( buffer1, buffer2, sizeof(buffer1) );  
    if (n>0) 
        printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);  
    else if (n<0) 
        printf ("'%s' is less than '%s'.\n",buffer1,buffer2);  
    else 
        printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
    return 0}

2.momcmp模拟实现

int my_momcmp(const void* str1, const void* str2,int num)
{
	assert(str1 && str2);
	while (*(char*)str1 == *(char*)str2)
	{
		num--;
		if (num == 0)
			return 0;
		str1 = (char*)str1 + 1;
		str2 = (char*)str2 + 1;
	}
	return (char*)str1 - (char*)str2;
  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小连~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值