strtok函数的使用说明和模拟实现,strerror函数、字符分类函数、字符转换函数的介绍

在今天的文章里,我将对字符串函数进行最后阶段的介绍,相信过了今天,你对字符串函数的了解将会更加深入。





strtok函数

请添加图片描述
由msdn查询可以得知,该函数的参数类型和返回类型是:
char* strtok(char* str,const char* sep),注意这里我们主要关注的是参数的类型和返回类型,不关注参数名字。

下面我对该函数进行大致的介绍。

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

我直接举个strtok函数的使用例子。

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "123456789@qq.com";   //包含了0个或者多个由分隔符的字符串中的一个或者多个分隔符分割的标记。
	char arr2[] = "@.";                 //由分隔符组成的字符集合。
	char* p = NULL;

	p = strtok(arr1,arr2);              //第一个参数第一次使用时传arr1字符串
	printf("%s\n",p);

	p = strtok(NULL,arr2);              //第一个参数第二次使用时传NULL
	printf("%s\n",p);

	p = strtok(NULL,arr2);              //第一个参数第三次使用时传NULL
	printf("%s\n",p);

	return 0;
}

运行结果如下:
请添加图片描述
由上面的一个小程序可以发现,strtok函数主要在str参数中寻找与sep参数相同的字符,将这些与sep参数相同的字符剔除掉,并返回那些与sep参数不相同的字符。

如果我们在使用strtok函数中,跟上面的小程序一样写的话,是比较低效的,我将对上面的代码进行改进。

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[] = "123456789@qq.com";
	char arr2[] = "@.";
	char* str = NULL;
	for(str = strtok(arr1,arr2);str != NULL;str = strtok(NULL,arr2))       //第一次使用时往第一个参数传参arr1,其他时候传参NULL
	{
	    printf("%s\n",str);
	}
	return 0;
}

运行结果如下;
请添加图片描述
相比第一次的代码,第二次代码看起来更加的简洁,我们以后对于strtok函数的使用时,尽量使用第二种写法。

接下来,我对strtok函数进行模拟实现。

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strtok(char* str,const char* sep)
{
    static char* s1 = NULL;
	static char* s2 = NULL;
	static int len1 = 0;
	static int count = 0;
	int len2 = 0;
	int i = 0;
	assert(sep != NULL);
	if(str != NULL)                //第一次进入
	{
		s1 = str;                           //s1记住初始位置
		len1 = strlen(str);
		len2 = strlen(sep);
		for(*str;*str != '\0';str++)        //移动str参数
		{			
            for(i=0;i<len2;i++)             //i为移动sep参数做准备
			{
			    if(i == 0)
				{
				    count++;
				}
				if(*str == *(sep+i))        //比较str字符串和sep字符串
				{
					*str = '\0';            //相同赋值为'\0'
					s2 = str;               //s2作为跳板
				    return s1;   
				}
			}
		}
	}
	else
	{
		s1 = s2 + 1;                        //s2作为跳板,s1记住初始位置
		len2 = strlen(sep);
		str = s1;                           //这一次str为NULL,所以要对str赋值
		for(*str;*str != '\0';str++)        //移动str参数
		{
		    for(i=0;i<len2;i++)             //为移动sep参数做准备
			{
			    if(i == 0)
				{
				    count++;
				}
				if(*str == *(sep+i))        //比较str参数和sep参数
				{
				    *str = '\0';            //str参数和sep参数相同就赋值为'\0'
					s2 = str;
					return s1;
				}
			}
		}
	}
	if(count > len1)
	{
		return NULL;
	}
	return s1;
}
int main()
{
	char arr1[] = "123456789@qq.com";
	char arr2[] = "@.";
	char* str = NULL;
	for(str = my_strtok(arr1,arr2);str != NULL;str = my_strtok(NULL,arr2))
	{
	    printf("%s\n",str);
	}
    return 0;
}

请添加图片描述
由运行结果可以得知,strtok函数的模拟符合strtok函数的功能。



strerror函数

请添加图片描述
由msdn查询可以得知,strerror函数的返回类型和参数类型是:char* strerror(int errnum)。

这个函数是用于返回errnum所对应的错误信息的,而这些错误信息是C语言中库函数报错的时候的错误码。

如下面这个例子:

#include<stdio.h>
#include<string.h>
int main()
{
    printf("%s\n",strerror(0));
	printf("%s\n",strerror(1));
    printf("%s\n",strerror(2));
	printf("%s\n",strerror(3));
	printf("%s\n",strerror(4));
	return 0;
}

运行结果如下:
请添加图片描述
这个程序打印的是错误码的内容,如错误码1对应的是运行结果的第一条,错误码2对应运行结果2的第二条。

错误码的信息一般储存在errno变量中,头文件为errno.h。

如:

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<errno.h>
int main()
{
	//以阅读的方式打开文档
	FILE* pf = fopen("text.txt","r");
	if(pf == NULL)
	{
	    printf("%s\n",strerror(errno));
		return 1;
	}

	//使用


	//释放
	fclose(pf);
	pf = NULL;

	return 0;
}

在这个程序中,我打开一个不存在的文档,失败的话,错误码就会被保存在errno变量中,然后用strerror函数进行解析错误码,最后用printf函数打印错误信息。

请添加图片描述
由运行结果可以得知,程序的确与我们的猜想一样。那么,这个错误码信息什么意思呢?翻译一下就行了嘛,没有这个文件或文件夹。

对于错误码的解析函数,还有另外一个较为重要的函数,那就是perror函数,头文件是stdio.h。

我将上面的代码进行略微改动。

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<errno.h>
int main()
{
	//以阅读的方式打开文档
	FILE* pf = fopen("text.txt","r");
	if(pf == NULL)
	{
	    perror("error");
		return 1;
	}

	//使用


	//释放
	fclose(pf);
	pf = NULL;

	return 0;
}

在上面的代码中,我将printf函数换成perror函数,perror函数包含了解析错误码和打印错误信息的功能。

请添加图片描述
由运行结果可知,错误信息多了个error:
我在上面代码中,对于perror函数是这样写的perror("error"),由此可以得知,perror会输出:传参信息+冒号+错误信息。

当然,我们可以不往perror函数传参,如:perror(“”),虽然有的编辑器不会报错,但是我们尽量不这样写,因为这样写是不符合perror的语法规则的。

字符分类函数介绍(头文件是:ctype.h。)

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

例子:

#include<stdio.h>
#include<ctype.h>
int main()
{
    char ch = 'a';
	int ret = isdigit(ch);
	printf("%d\n",ret);
	return 0;
}

请添加图片描述
如上面判断是不是数字字符,是就返回非0,不是就返回0。

字符转换函数(头文件是:ctype.h。)

函数作用
tolower大写字母转小写
toupper小写字母转大写

例子:

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

请添加图片描述
如上面的toupper函数一样,将字符’w’转换为’W’。

直到今天,字符串函数终于讲完了,如果感觉对你有用的话,那么就关注点一点,下期更精彩。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值