部分字符函数与字符串函数的讲解

说到字符函数,我们见过很多,比如strlen,strcpy,strcat......

这时候就会有人说还有sizeof,其实sizeof不是库函数,他其实是操作符

 但是你听说过以下库函数么?

所以说字符串的函数有很多,我们这里介绍几个常用的;

 练习一:大写转小写/小写转大写

正常情况下,看到这题我们会联想到其可以使用对应的ASCII值进行转换 (大写对应的ASCII值比其小写小32)

代码如下:(小写转大写)

int main()
{
    char a = 'a';
    a = a - 32;
    printf("%c", a);
    return 0;
}

但是如果你知道toupper这个函数就会更方便

头文件#include<ctype.h>

#include <ctype.h>
int main()
{
    char a = 'a';
    a = toupper(a);
    printf("%c", a);
    return 0;
}

打印A 

 同样有小写转大写,那就有大写转小写

#include <ctype.h>
int main()
{
    char a = 'A';
    a = tolower(a);
    printf("%c", a);
    return 0;
}

打印a

strlen的实现

其该函数就为数到'\0',停止,不计算\0 

 首先strlen的返回值为size_t

实现代码如下 

size_t my_strlen(const char* string)
{
	size_t count = 0;
	while (*string++ != '\0')
	{
		count++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	size_t ret=my_strlen(arr);
	printf("my_strlen=%zd\n", ret);
	printf("strlen=%zd", strlen(arr));
	return 0;
}

strstr函数的实现

strstr函数的介绍:

 

实现如下:

char* my_strstr(const char* string, const char* str)
{
	assert(string);
	assert(str);
	char* cur = (char*)string;
	char* s2 = (char*)str;
	if (*str=='\0')
	{
		return (char*)string;
	}
	while (*cur)
	{
		string = cur;
		s2 = str;
		while (*s2 == *string && *string && *s2)
		{
			s2++;
			string++;
		}
		if (!*s2)
			return cur;
		cur++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "asdasds";
	char arr2[] = "sds";
	char* ret=my_strstr(arr1, arr2);
	printf("%s", ret);
	return 0;
}

strcpy函数的实现

strcpy函数就为字符拷贝

 函数实现如下:

#include<stdio.h>
#include<string.h>
char* my_strcpy(char* strDestination, const char* strSource)
{
	char* ret = strDestination;
	while (*strSource != '\0')
	{
		*strDestination++ = *strSource++;
	}
	*strDestination = '\0';
	return ret;
}
int main()
{
	char arr1[100] = "aaaaaaa";
	char arr2[] = "bbbb";
	my_strcpy(arr1, arr2);
	return 0;
}

strcat函数的实现

strcat就为字符串连接函数

介绍如下:

 代码实现如下:

#include<stdio.h>
#include<string.h>
char* my_strcat(char* strDestination, const char* strSource)
{
	char* ret = strDestination;
	size_t sz = strlen(strDestination);
	strDestination += sz;
	while (*strSource != '\0')
	{
		*strDestination++ = *strSource++;
	}
	*strDestination = '\0';




	return ret;
}
int main()
{
	char arr1[100] = "aaaaaaa";
	char arr2[] = "bbbb";
	my_strcat(arr1, arr2);
	return 0;
}

strcmp函数的实现

代码实现如下:

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

int my_strcmp(const char* str1, const char* str2)
{
	while (*str1 && *str2)
	{
		if (*str1 == *str2)
		{
			str1++, str2++;
		}
		else
		{
			return *str1 - *str2;
		}
	}
	if (*str1 )
	{
		return 1;
	}
	else if(*str1==*str2&&*str1=='\0')
	{
		return 0;
	}
	else
	{
		return -1;
	}
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcedf";
	int ret=my_strcmp(arr1, arr2);
	if (ret > 0)
	{
		printf("arr1>arr2");
	}
	else if (ret == 0)
	{
		printf("arr1=arr2");
	}
	else
	{
		printf("arr1<arr2");
	}
	return 0;
}

 两种报错函数:(需要引头文件#include<errnor>

第一种:strerror

使用方法:

#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印⼀下0~10这些错误码对应的信息 
int main()
{
    int i = 0;
    for (i = 0; i <= 10; i++) 
    {
        printf("%s\n", strerror(i));
    }
    return 0;
}

但搜索相关知识后的是该库函数返回值为

对应的所有报错信息:

第二种:perror

 perror使用的更多,其输出错误信息更方便,

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
    FILE* pFile;
    pFile = fopen("unexist.ent", "r");
    if (pFile == NULL)
        perror("Error opening file unexist.ent");
    return 0;
}

输出:Error opening file unexist.ent: No such file or directory

库函数带n系列

比如说strcat与strncat:

区别在于:

  1. strcat 没有指定追加的长度限制,会一直追加直到遇到第一个空字符('\0')为止,因此需要确保目标字符串有足够的空间来容纳被追加的字符串。

    例如:strcat(dest, src);

  2. strncat 则允许指定最多追加的字符数,避免了可能的缓冲区溢出问题。第三个参数指定要追加的最大字符数。

    例如:strncat(dest, src, n);

因此,如果你能够确定目标字符串有足够的空间来容纳被追加的字符串,可以使用 strcat;如果想要避免潜在的缓冲区溢出问题,可以使用 strncat 并指定追加的最大字符数。

 所以带n的可以避免很多问题;

strncat

其代码接收时利用char* 按照字节单位进行函数内的操作,返回值同样为char* 

代码实现如下:

char* my_strncat(char* str1, const char* str2)
{
	char* ret = str1;//保存头
	while (*str1)//一直到\0
	{
		str1++;
	}
	while (*str2)
	{
		*str1 = *(char*)str2;
		str1++;
		str2++;
	}


	//添加\0
	*str1='\0';
	return ret;
}
int main()
{
	char arr1[150] = "asdfg";
	char arr2[] = "sss";
	char* ret=my_strncat(arr1,arr2);
	printf("%s", ret);
	return 0;
}

代码其实与strcat差不多

strncpy

实现代码如下:

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


char* my_strncpy(char* str1, const char* str2, int n)
{
	assert(str1 && str2);
	int i = 0;
	for (i = 0; str2 != '\0' && i < n; i++)
	{
		str1[i] = str2[i];
	}
	if (i < n)//符合库函数给的标准
	{
		str1[i] = '\0';
	}
	return str1;
}
int main()
{
	char arr1[150] = "asdfgh";
	char arr2[] = "asd";
	char* ret=my_strncpy(arr1,arr2,3);
	//char* ret=strncpy(arr1,arr2,3);
	printf("%s", ret);
	return 0;
}

mem系列

memcpy和strcpy是C语言中常用的字符串处理函数,它们的区别主要在于功能和用法上:

  1. strcpy:用于将一个字符串复制到另一个字符串中,直到遇到空字符'\0'为止。其函数原型为:

char *strcpy(char *dest, const char *src);

其中,dest表示目标字符串的指针,src表示源字符串的指针。strcpy会复制整个源字符串(包括'\0'结束符)到目标字符串中,如果源字符串比目标字符串长,可能会导致缓冲区溢出。

  1. memcpy:用于将一段内存区域的数据复制到另一段内存区域中,可以复制任意类型的数据,不仅限于字符串。其函数原型为:

void *memcpy(void *dest, const void *src, size_t n);

其中,dest和src分别表示目标内存区域和源内存区域的指针,n表示要复制的字节数。memcpy只关心字节数,不会在遇到'\0'时停止复制,因此更适合用于处理二进制数据或非字符串数据的复制操作。

总的来说,strcpy适用于字符串的复制操作,而memcpy适用于一般的内存数据复制操作。在使用时需要根据具体的需求选择合适的函数。

 其需要注意的是接收使用的void*类型的指针

void* 类型指针不能进行解引用需要进行强制类型转化

代码实现如下:

void* my_memcpy(void *dest,void* str,size_t count)
{
	assert(dest);
	assert(str);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)str;
		dest = (char*)dest+1;
		str = (char*)str+1;
	}


	return ret;
}
int main()
{
	char arr1[150] = "iiiiiiiii";
	char arr2[] = "ssssss";
	my_memcpy(arr1, arr2,5);
	printf("%s", arr1);
	return 0;
}

但是如果我们传参为arr1+2与arr1呢?,那么这个代码就会出现问题,这时候就需要利用函数memmove:

实现如下:

void* my_memmove(void* dest,const void* str, size_t count)
{
	assert(dest);
	assert(str);
	void* ret = dest;
	char* s1 = (char*)dest;
	char* s2 = (char*)str;
	if (dest < str)//从前 -》 后
	{
		while (count--)
		{
			*s1++ = *s2++;
		}
	}
	else//后 -》 前
	{
		s1 = s1 + count;
		s2 = s2 + count;
		while (count--)
		{
			*s1-- = *s2--;
		}
	}
	return ret;
}


int main()
{
	char arr1[150] = "iissssiii";
	char arr2[] = "ssssss";
	my_memmove(arr1, arr1+2,5);
	printf("%s", arr1);
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值