字符函数和字符串函数

字符串函数

求字符串长度

strlen

1、注意返回size_t,无符号数,参数为char*。

2、以 '\0' 作为结束标识符,返回字符串开头到 '\0' 中间的字符个数。

3、注意与sizeof函数不同

int main()
{
	char arr[20] = "abc";
	printf("%zd\n", strlen(arr));
	printf("%zd", sizeof(arr));
}

4、模拟实现

三种实现方法

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//1.计数器
//2.递归
//3.指针-指针
size_t my_strlen1(const char* str)
{
	size_t ret = 0;
	while (*str++ != '\0')
	{
		ret++;
	}
	return ret;
}
size_t my_strlen2(const char* str)
{
	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return my_strlen2(str + 1) + 1;
	}
}
size_t my_strlen3(const char* str)
{
	char* left = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - left;
}
int main() 
{
	char arr[10] = { 0 };
	gets(arr);
	printf("%zd ", my_strlen1(arr));
	printf("%zd ", my_strlen2(arr));
	printf("%zd", my_strlen3(arr));
	return 0;
}

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

strcpy

字符串拷贝函数

1、目标空间没有const修饰,必须可以更改。

2、该函数会将源字符串的 '\0' 拷贝到目标空间,所以源字符串必须以 '\0' 结束。

注意上面代码中 arr2 将 arr1[4] 原本的 'x' 修改为 '\0' 。

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

4、模拟实现

#include<stdio.h>
#include<assert.h>
//char* strcpy(char* destination, const char* source)
char* my_strcpy(char* dest, const char* sour)
{
	assert(dest && sour);
	char* ret = dest;
	while (*dest++ = *sour++){}
	return ret;
}
int main()
{
	char arr1[20] = { 0 };
	char arr2[20] = { 0 };
	gets(arr2);
	printf("%s", my_strcpy(arr1, arr2));
	return 0;
}

strcat

字符追加函数

1、

2、目的地中的第一个 '\0' 会被源字符串覆盖,需要源字符串以 '\0' 结束。

3、目的地与源字符串不能重叠。

4、模拟实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* sour)
{
	assert(dest && sour);
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *sour++){}
	return ret;
}
int main()
{
	char arr1[20] = { "abcde\0xxxxx" };
	char arr2[20];
	gets(arr2);
	printf("%s", my_strcat(arr1, arr2));
	return 0;
}

strcmp

字符比较函数

1、

2、从每个字符串的第一个字符开始比较,直至找到不同或者 '\0'。

3、第一个字符串大于第二个字符串返回大于0的数字,相等返回0,小于返回小于0的数字。

4、模拟实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
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;
}
int main()
{
	char arr1[10] = "abc";
	char arr2[10];
	gets(arr2);
	printf("%d", my_strcmp(arr1, arr2));

	return 0;
}

长度受限制的字符串函数

strncpy

拷贝num个字符的拷贝函数

1、

2、如果源字符串小于num,就会在拷贝完源字符串后在后面追加 0 ,直至num个

但如果源字符串大于num,字符串拷贝之后将会读取溢出

因为该函数不会在拷贝后在末尾隐式追加终止符。

strncat

追加num个字符的追加函数

1、

2、将源字符串的前num个字符追加给目的地,外加上一个终止符。

3、如果源字符串小于num个字符,则仅复制终止符前的字符。

strncmp

最多比较num个字符的比较函数

1、

2、函数开始比较字符串的每一个字符,直到出现不同或终止符或者num个字符比较完毕。

字符串查找

strstr

字符串查找函数

1、

2、返回指向str1中第一次出现str2的指针,如果没出现则返回null。

3、模拟实现

#include<stdio.h>
const char* my_strstr(const char* str1, const char* str2)
{
	if (*str2 == '\0')
	{
		return str1;
	}
	char* ret = str1;
	char* p = str2;
	while (*str1)
	{
		while (*str1 == *str2)
		{
			*str1++;
			*str2++;
			if (*str2 == '\0')
			{
				return ret;
			}
		}
		ret++;
		str2 = p;
		str1 = ret;
	}
	return NULL;
}
int main()
{
	char arr1[20] = "abcdefg";
	char arr2[20];
	gets(arr2);
	printf("%s", my_strstr(arr1, arr2));
	return 0;
}

strtok

字符串拆分函数

1、

2、delimiters是个字符串,定义了分隔符的字符集合,作为str拆分的标记。

3、函数会找到str中的下一个标记,并用 '\0' 替换这个标记然后作为结尾,返回一个指向这里的指针。

4、当函数的第一个参数不为null,即是第一次拆分该字符串,函数将会找到第一个标记,并会记录这个标记的位置,用作第二次开始。当函数的第一个参数为null,即不是第一次拆分了,函数根据上一次拆分记录的位置开始找下一个标志。如果找到了终止符,即该字符串不存在更多的标记,则返回null。

5、举例

#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "- This, a sample string.";
	char* pch;
	pch = strtok(str, " ,.-");
	while (pch != NULL)
	{
		printf("%s\n", pch);
		pch = strtok(NULL, " ,.-");
	}
	return 0;
}

错误信息报告

strerror

错误码翻译函数

1、

2、返回错误码所对应的错误信息。

字符操作函数

字符分类函数

字符转换函数

大写转小写:int tolower(int c);

小写转大写:int toupper(int c);

内存操作函数

memcpy

内存块拷贝函数

1、

2、将源指向的位置的num个字节的值,直接拷贝给目标指向的内存块。

3、遇到 '\0' 不会停止,而是会将它一并拷贝。

4、标准库中该函数的目标函数与源函数不应重叠,重叠复制的结果都是未定义的,但是在vscode2020中,memcpy函数更加强大,能够自我拷贝。

5、根据标准库建议模拟实现

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

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

int main()
{
	int arr1[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int arr2[10] = { 0 };
	my_memcpy(arr1 + 3, arr2, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

memmove

内存块移动函数

1、

2、在标准库中,memmove与memcpy的区别就是它源内存块与目的内存块重叠可以处理。

3、模拟实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* sour, size_t num)
{
	assert(dest && sour);
	if (sour < dest)
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)sour + num);
		}
	}
	else
	{
		for (int i = 0; i < num; i++)
		{
			*((char*)dest + i) = *((char*)sour + i);
		}
	}
}
int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	my_memmove(arr, arr+2, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

memset

1、

2、将ptr指向的num个字节设置为value,value以int形式传递,以char填充。

3、注意更改是将num个字节更改,下列两个运行实例。

这是char类型的字符串,更改从str开始的三个字节为 'x' 。

这是int类型的数组,更改str+3地址的三个字节,注意内存块的变化。

memcmp

内存块比较函数

1、

2、与strcmp不同,在找到 '\0' 之后仍会继续比较,要把num个字节比较完毕。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值