字符函数和字符串函数

1.前言

相信大家写代码的时候,对字符串的处理是很频繁的,如果我们用自定义函数来处理,不免有点麻烦,今天我带大家了解并模拟实现c语言库里提供的函数,可以大大简化我们的工作。

2.strlen函数

2.1介绍

size_t strlen ( const char * str );//库函数的定义

(1)该函数是用来求字符串长度的,字符串以‘\0’结尾,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数**(不包含 ‘\0’ )**。
(2)该函数的返回类型是size_t,这是c语言库里面typedef了一下,其实是unsigned int类型。
(3)使用该函数要确保传的字符数组和字符串以’\0’结束。

这里我们来看一下第二点要注意的地方

#include <stdio.h>
int main()
{
 const char*str1 = "abcdef";
 const char*str2 = "bbb";
 if(strlen(str2)-strlen(str1)>0)
 {
 printf("str2>str1\n");
 } 
 else
 {
 printf("srt1>str2\n");
 }
 return 0;
}

这个程序的结果是打印str2>str1,大家可能会困惑,str1的长度不是明显大于str2吗,这是因为这个函数的返回值是无符号类型的,两个无符号类型的数字相减肯定是大于零的,所以该程序是输出下面这个。

2.2模拟实现

int my_strlen(const char* s)
{
	int count = 0;
	while (*s++)
	{
		count++;
	}
	return count;
}
int my_strlen1(const char* s)
{
	if (*s == '\0')
	{
		return;
	}
	return my_strlen(s + 1) + 1;
}
int main()
{
	char* s = "asdascas";
	printf("%d", my_strlen1(s));


	return 0;
}

3.strcpy、strncpy函数

3.1介绍

char* strcpy(char * destination, const char * source );
char * strncpy(char * destination, const char * source,size_t num);

该函数的作用是将source的字符串考拷贝到destination中。
(1)source字符串必须以‘\0’结尾
(2)这个函数会把source的‘\0’拷贝过去
(3)使用该函数注意destination的空间要大于source的空间
(4)将source中的num个字符拷贝到destination中去
(5)如果num的个数大于source中的个数,后面的会自动补‘\0’

3.2模拟实现

char* my_strcpy(char* des, const char* sour)
{
	char* ret = des;
	while (*des++ = *sour++);
	return ret;
}
int main()
{
	char* sour = "jadha";
	char des[20] = {0};
	my_strcpy(des, sour);
	printf("%s",des);
}

4.strcat、strncat函数

char * strcat ( char * destination, const char * source );
char* strncat(char* destination,const char * source,size_t num);

4.1介绍

该函数的作用是将source字符串连接到destination后面。
(1)目标空间必须可修改
(2)destination和source字符串必须以‘\0’结尾
(3)不能自己连接到自己
(4)destination的空间要足够大

这里我们来解释一下为什么不能传两个相同的指针过去(自己连接自己)
在这里插入图片描述

4.2模拟实现

char* my_stract(char* des, const char* sour)
{
	char* ret = des;
	while (*des != '\0')
	{
		des++;
	}
	while (*des++ = *sour++);
	return ret;
}
int main()
{
	char des[20]= "asd ";
	char* sour = "asd";
	printf("%s",my_stract(des,sour));
	return 0;
}

5.strcmp、strncmp函数

5.1介绍

int strcmp(const char* str1,const char* str2);
int strncmp(const char* str1,const char* str2,size_t num);

这个函数的作用是比较两个字符串的大小。
(1)str1和str2俩个字符串必须要以‘\0’结尾
(2)num表示比较到第几个字符。
(1)str1比str2大返回大于零的数,相等返回零,小返回负数

5.2模拟实现

int my_strcmp(const char* s, const char* s1)
{
	while (*s == *s1)
	{
		if (*s == '\0')
			return 0;
		s++;
		s1++;
	}
	return *s - *s1;
}

6.strstr函数

6.1介绍

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

(1)该字符串的作用是在str1找到第一次出现str2的地方
(2)如果找到了则返回地址,没找到返回null

6.2模拟实现

char* my_strstr(const char* s1, const char* s2)
{
	char* begin1 = s1;
	char* end1 = s1;
	char* begin2 = s2;
	char* end2 = s2;

	while (*begin1 != '\0')
	{
		while (*end1 == *end2 && *end1 != '\0' && *end2 != '\0')
		{
			end1++;
			end2++;
		}
		//找到了返回首字符地址
		if (*end2 == '\0')
		{
			return begin1;
		}
		//没找到,调整指针位置,继续一下轮循环
		else
		{
			begin1++;
			end1 = begin1;
			end2 = begin2;
		}
	}
	return NULL;
}

7.strtok函数

7.1介绍

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

(1)该函数的作用是通过特定符号来切割字符串。
(2)sep参数是个字符串,定义了用作分隔符的字符集合。
(3)str参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分 割的标记。
(4)该函数会找到下一个分割符并将其变成’\0’,然后返回指向该处的指针,如果遍历到str末尾,会返回NULL(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
(5)若该字符串不含分割字符集中的任意一个字符,则返回NULL
(6)strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
(7)strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
例子:

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

8.strerror函数

8.1介绍

char * strerror ( int errnum );

(1)该函数的作用是返回错误码对应的错误信息
(2)#include <errno.h> //必须包含的头文件

9.字符函数

9.1字符分类函数介绍

(1)iscntrl() 任何控制字符
(2)isspace() 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
(3)isdigit 十进制数字 0~9
(4)isxdigit 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A-F
(5)islower 小写字母a~z
(6)isupper 大写字母A~Z
(7)isalpha 字母a-z或A~Z
(8)isalnum 字母或者数字,a-z,A-Z,0~9
(9)ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
(10)isgraph 任何图形字符
(11)isprint 任何可打印字符,包括图形字符和空白字符
总结:如果上面的函数的参数符合后面的则返回真,否则为假

9.2字符转换函数介绍

int tolower ( int c );
int toupper ( int c );

(1)这两个函数的作用是将小写字符转换成大写字符,小写字符转换成大写字符。

/* isupper example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
  int i=0;
  char str[]="Test String.\n";
  char c;
  while (str[i])
 {
    c=str[i];
    if (isupper(c)) 
        c=tolower(c);
    putchar (c);
    i++;
 }
  return 0;
 }

10.memcpy函数

10.1介绍

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

(1)该函数的作用是将source中的num个字节考拷贝到destination上去
(2)num的单位是字节
(3)遇到‘\0’不会停下来(这一点是该函数和strcpy、strncpy不一样的地方)
(4)假如dsetination和source的空间有重叠的部分,那么该函数的结果是不可预料的,因为可能会覆盖
(5)使用的时候要确保destination的空间足够大

10.2模拟实现

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

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

int main()
{
	char destination[20] = { 0 };
	char* source = "hxbjqhxbcqyi";
	printf("%s",(char*)my_memcpy(destination,source,6));
	return 0;
}

11.memmove

11.1介绍

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

(1)该函数的作用和memcpy函数作用一样
(2)该函数可以使用在有重叠部分的两个空间

11.2模拟实现

void* my_memmove(void* destination, const void* source, size_t num)
{
	assert(destination && source);
	void* ret = destination;
	//从前往后拷贝
	if (destination < source)
	{
		while (num--)
		{
			*(char*)destination = *(char*)source;
			(char*)destination = (char*)destination + 1;
			(char*)source = (char*)source + 1;
		}
	}
	//从后往前拷贝
	else
	{
		while (num--)
		{
			*((char*)destination + num+1) = *((char*)source + num+1);
		}
	}

	return ret;
}
int main()
{
	char arr[20] = { 's','d','v','c','w','r','t','x','q','d','m' };
	printf("%s", (char*)my_memmove(arr+3, arr, 6));
	return 0;
}

12.memcmp

12.1介绍

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

(1)该函数的作用是比较ptr1和ptr2中前num个字节的大小
(2)num的单位是字节
(3)大于返回大于0,小于返回小于0,等于返回0

/* memcmp example */
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值