C语言进阶-字符串

0. 前言

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

1. 函数介绍

1.1 strlen

size_t strlen (const char* str);

  • 字符串以'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包含'\0')。
  • 参数指向的字符串必须要以'\0'结束。
  • 注意函数的返回值为 size_t 是无符号的。(易错)
  • 学会 strlen 函数的模拟实现。
size_t my_strlen(const char* ch)
{
	int i = 0;
	size_t sz = 0;
	while (ch[i] != 0)
	{
		i++;
		sz++;
	}
	return sz;
}
int main()
{
	char arr[] = "abcdef";		//abcdef\0
	size_t len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

1.2 strcpy

char* strcpy(char* destination,const char* source);

  • 源字符串必须以'\0'结束。
  • 会将源字符串中的'\0'拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。
  • 学会模拟实现。
char*  my_strcpy(char* d1, const char* s1)
{
	assert(d1&&s1);
	char* ret = d1;
	while (*d1++ = *s1++)
	{
		;
	}
	return ret;
}
int main()
{
	char* p = "abcdef";
	char arr[] = "bit";
	strcpy(p, arr);	//目标区域不可修改
	return 0;

1.3 strcat

char* strcat(char* destination,const char* source);

  • 源字符串必须以'\0'结束
  • 目标空间必须足够的大,能容下源字符串的内容。
  • 目标空间必须可修改。
char* my_strcat(char* d1, const char* s1)
{
	assert(d1 && s1);
	char* ret = d1;
	while (*d1++);
	while (*d1++ = *s1++);
	return ret;
}

1.4 strcmp

int strcmp(const char* str1,const char* str2);

  • 第一个字符串大于第二个字符串,则返回大于0的数字。
  • 第一个字符串等于第二个字符串,则返回0。
  • 第一个字符串小于第二个字符串,则返回小于0的数字。
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (1)
	{
		if (*str1 == *str2)
		{
			str1++;
			str2++;
		}
		else
			return (*str1) - (*str2);
		
	}
}

1.5 strstr

char* strstr(const char* str1,const char* str2);

在一个字符串中找出子字符串。

char* my_strstr(const char* str1,const char* str2)
{
	assert(str1 && str2);
	const char* s1 = str1;
	const char* s2 = str2;
	const char* p = str1;
	while (*s1 != 0&&*s2!=0)
	{
		if (*s1 == *s2)
		{
			s1++; s2++;
		}
		else
		{
			p++;
			s1 = p;
			s2 = str2;
		}
	}
	if (*p == 0)
		return NULL;
	else
		return p;
}

1.6 strtok

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

sep参数是个字符串,定义了用作分隔符的字符集合

第一个参数指定的一个字符串,它包含了0个或多个由sep字符串中一个或多个分隔符切割的标记。

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

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

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

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

1.7 strerror

char* strerror(int errnum);

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

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

int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	return 0;
}

字符分类函数:

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘’,换页‘\f’,换行‘\n’,回车‘\r’,制表符‘\t’或者垂直制表符‘\v’
isdigit十进制数字0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

字符转换:

int tolower(int c);

int toupper(int c);

1.8 memcpy

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

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到‘\0’的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。
//memcpy负责拷贝两块独立空间中的数据
//重叠内存的拷贝,使用memmove
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	for (int i = 0; i < num; i++)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

1.9 memmove

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	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;
}

1.10 memcmp

int memcmp(const void* ptr1,

                     const void* ptr2,

                     size_t num);

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

1.11 memset

void* memset(void* ptr,int value,size_t num);

以字节初始化内存内容。

char arr[] = "hello bit";
memset(arr, 'x', 5);
printf("%s\n", arr);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值