字符函数和字符串函数

前言

在c语言的编程过程中,我们经常要处理字符和字符串,为了方便字符和字符串操作,c语言中提供了一系列库函数。

一.字符函数

C语言有一些函数是专门做字符分类的,也就是一个字符是属于什么类型的字符,使用该类函数要包含头文件ctype.h

下面我们用一段代码,将字符串中的小写字母转大写来带大家熟悉一下函数的使用

#include<stdio.h>
#include<ctype.h>
int main()
{
	int i = 0;
	char str[]="Test String.\n";
	while(str[i] != '\0')
	{
		if(islower(str[i])) //判断是否为小写字母 
		{
			str[i] -= 32;
		}
		i++;
	 }
	 printf("%s\n",str); 
     return 0;
} 

除了以上的函数c语言还提供了2个字符转函数:

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写

int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

 有了这两个函数我们就可以改良上面的小案例

#include<stdio.h>
#include<ctype.h>
int main()
{
	int i = 0;
	char str[]="Test String.\n";
	while(str[i] != '\0')
	{
		if(islower(str[i])) //判断是否为小写字母 
		{
			str[i] = toupper(str[i]);
		}
		i++;
	 }
	 printf("%s\n",str); 
}

 由于上面的函数很简单,小编就不在这里给大家一一叙述了,感兴趣的兴趣可以自己试一下。

二.字符串函数

1.strlen的使用和模拟实现

《1》strlen的使用

strlen的功能:将首地址传入,统计从首地址到'\0'的字符个数。

strlen的语法形式:  size_t   strlen (const char * str);

strlen使用的注意事项

• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包含 '\0' )。

• 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是⽆符号的( 易错 )

• strlen的使⽤需要包含头⽂件                 

这里我们着重说一下函数的返回值是size_t(无符号整形)这种情况:

#include<stdio.h>
#include<string.h>
int main()
{
	if(strlen("abc") - strlen("abcdef") > 0)
	 {
	 	printf(">");
	 }
	 else
	 {
	 	printf("<=");
	 }
	 return 0;
} 

 从这段代码我们可以看出strlen("abc")的值是3,strlen("abcdef")的值是6, 3-6得到的是-3,而-3应该小于0,应输出<=而结果输出>这究竟是为什么呢?话不多说我们直接看图。

 

相信看了上面的图大家对size_t类型有了了解 ,那么上方代码我们有什么解决方法呢?

我们只需要在strlen前加上int类型的强制类型转换即可解决问题,下面上代码:

#include<stdio.h>
#include<string.h>
int main()
{
	if((int)strlen("abc") - (int)strlen("abcdef") > 0)
	 {
	 	printf(">");
	 }
	 else
	 {
	 	printf("<=");
	 }
	 return 0;
} 

《2》strlen的模拟实现

 对于strlen的模拟实现我们介绍三种方法

 (1)计数器法
size_t my_strlen(const char *arr)
{
	size_t count = 0;
	int i = 0;
	while(arr[i])
	{
		count++;
		i++;
	}
	return count;
	
}

该代码的实现思想是在函数中添加一个计数器,遍历整个字符串,若字符串不为'\0',count++,若为'\0'则跳出循环返回count的值。

(2)指针-指针

 

size_t my_strlen(const char *arr)
{
	size_t count = 0;
	const char *arr2 = arr;
	while(*arr2)
	{
		arr2++;
	}
	return arr2 - arr;
	
}

该函数的思想是在函数中在创建一个字符指针类型的变量arr2,把arr1的地址给arr2,然后arr2依次遍历字符串中的数据直到遇到'\0',跳出循环此时arr2保存的是'\0'的地址,arr2-arr表示的时两地址之间的元素个数(该字符串'\0'之前的元素个数),然后返回arr2-arr的值。

(3)递归方法实现
size_t my_strlen(const char *arr)
{
	
	if(*arr != 0)
	{
		return 1 + my_strlen(arr+1);
	}
	else
	{
		return 0;
	}
	
	
}

 

 由上图可知该方法是利用递归函数把问题,分成若干个子问题解决。

 2.strcpy函数的使用和模拟实现

《1》strcpy的使用

strcpy函数的功能:是将源字符串拷贝到目标字符串中。

strcpy函数的语法形式:char* strcpy(char * destination, const char * source );

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] ={0};
	char arr2[]="hello word";
	char *t = NULL;
	t = strcpy(arr1,arr2);
	printf("%s\n",arr1);
	printf("%s\n",t);
	return 0; 
}

 

 strcpy注意事项:

strcpy返回类型为char*

源字符串必须以 '\0' 结束

• 会将源字符串中的 '\0' 拷⻉到⽬标空间。

⽬标空间必须⾜够⼤,以确保能存放源字符串。

⽬标空间必须可修改

《2》strcpy的模拟实现
char *my_strcpy(char *arr1 , const char *arr2)
{
	assert(arr1 && arr2);
	char *cur = arr1;
	while(*arr1++ = *arr2++);
	;
	return cur;
}

该代码的实现思想非常简单,创建一个指针变量cur存arr1存放第一个元素首地址的位置,分别遍历arr1和arr2,同时将arr2的值赋给arr1,当arr2的值为'\0'时跳出循环,并返回cur(记录的时arr1第一个元素首地址)。

3.strcat函数的使用和模拟实现

《1》strcat的使用

strcat函数的功能:是将源字符串中的数据追加到目标字符串后面,会将源字符串的'\0'追加到目标字符串当中。

strcat函数的语法形式:char * strcat(char *dest, const char*src)

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20]="abcd";
	char arr2[]="efgh";
	char *cur = NULL;
	cur = strcat(arr1,arr2);
	printf("%s\n",arr1);
	printf("%s\n",cur);
	return 0;
}

 

 strcat的注意事项:

源字符串必须以 '\0' 结束

• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。

⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。

• ⽬标空间必须可修改

 《2》strcat的模拟实现
char *my_strcat(char *arr1 , const char *arr2)
{
	char * cur = arr1;
	while(*arr1)
	{
		arr1++;
	}
	while(*arr1++ = *arr2++)
	{
		;
	}
	return cur;
	
}

首先,创建一个字符指针变量cur,用来存储arr1首元素的首地址,然后找到arr1的末尾节点,从arr1末尾节点开始追加arr2的元素直到追加结束。

4.strcmp函数的使用和模拟实现 

《1》strcmp的使用

strcmp函数的功能:是比较两字符串的大小从首个字符串逐一往后比较,直到有一方先结束,

字符串1 > 字符串2        返回1

字符串1 < 字符串2        返回-1

字符串1 == 字符串2      返回0

strcmp函数的语法形式:int strcmp (const char * str1, const char * str2)

 

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "abcp";
	char arr3[] = "abcdeeg";
	char arr4[]	= "abcdefg";
	printf("arr1和arr2比:"); 
	printf("%d\n",strcmp(arr1,arr2));
	printf("arr1和arr3比:"); 
	printf("%d\n",strcmp(arr1,arr3));
	printf("arr1和arr4比:"); 
	printf("%d\n",strcmp(arr1,arr4));
	return 0;
}

 

strcmp是比较两字符ASCLL码值大小

《2》strcmp函数的模拟实现 
int my_strcmp(const char *arr1 , const char *arr2)
{
	assert(arr1 && arr2);
	while(*arr1 == *arr2)
	{
		if(*arr1 == '\0')
		return 0;
		arr1++;
		arr2++;
	}
	return *arr1 - *arr2;
}

首先,由arr1和arr2的值比较如果相等不断往后遍历,若同时为'\0',则证明两个字符串相等否则继续遍历知道找到不相等的跳出循环,然后,返回*arr1-*arr2,若*arr1比*arr2大则返回大于0的数字,否则返回小于0的数字。

5.strstr函数的使用和模拟实现 

《1》strstr函数的使用

函数返回字符串str2在字符串str1中第⼀次出现的位置。

字符 串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。

 

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abbcdbcdef";
	char arr2[] = "db";
	char *cur = NULL;
	cur = strstr(arr1,arr2);
	printf("%s\n",cur);
	return 0;
}

 《2》strstr的模拟实现
char *my_strstr(const char *arr1,const char *arr2)
{
	const char *cur = arr1;//记录每次字符比较的最初位置 
	const char *s1 = NULL ,*s2 = NULL;//arr1和arr2中的移动变量 
	if(*arr2 == '\0')
	return ((char*)arr1);
	
	
	while(*cur)
	{
		s1 = cur;
		s2 = arr2;
		while(*s1 == *s2)
		{
			s1++;
			s2++;
		}
		if(*s2 == '\0')
		return ((char *)cur);
		cur++;
	} 
	
	
	return NULL;
}

首先创建一个指针变量cur存储arr1的地址,然后创建s1,s2记录arr1和arr2中的子字符串位置进行比较,创建完成后,判断arr2是否为空字符串,若为空字符串直接返回arr1字符串首元素的首地址,如果arr2不为空字符串,进入while循环每次将s1和s2的值分别初始化成cur和arr2用来刷新查找位置,判断s1和s2中的值是否相等,如果相等则继续往下比较直到不满足条件跳出循环判断s2的值是否为0,若为0返回cur的地址,否则cur++继续向后查找,重复上述步骤,若arr2不在arr1中直到cur为'\0'结束查找返回NULL

 6.strtok函数的使用

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

• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合

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

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

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

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

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

 

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "15483189@163.com";//带分隔符的字符串
	char arr2[] = "@.";//存储分隔符的字符串
	char *ret = NULL;
	for(ret = strtok(arr1,arr2) ; ret ;ret = strtok(NULL,arr2))
	{
		printf("%s\n",ret);
	}
	return 0;
 } 

 

7.strncpy函数的使用

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

与strncpy函数差不多,但多了以下几点:

•拷⻉num个字符从源字符串到⽬标空间。

• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

 

 

8.strncat函数的使用

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

与strncat函数差不多,但多了以下几点:

•将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字 符

•如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾

 

 

 

9.strcmp函数的使用

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

与strncmp函数差不多,但多了以下一点:

•⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀ 样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0.

 

 

 

10.strerror函数的使用

strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。

在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。 

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
 	FILE * pFile;
 	pFile = fopen ("hhh.txt","r");
 	if (pFile == NULL)
 	printf ("错误是: %s\n", strerror(errno));
 	return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值