C语言字符串函数和字符串函数

1. 字符分类函数
2. 字符转换函数
3. strlen的使⽤和模拟实现
4. strcpy的使⽤和模拟实现
5. strcat的使⽤和模拟实现
6. strcmp的使⽤和模拟实现
7. strncpy函数的使⽤
8. strncat函数的使⽤
9. strncmp函数的使⽤
10. strstr的使⽤和模拟实现
11. strtok函数的使⽤
12. strerror函数的使⽤

1.字符分类函数

下面是几个函数的例子,其余可以自行尝试(不要忘记头文件)。 

islower函数的运用:
如果不使用函数则需要这样
#include<stdio.h>
int main()
{
	char arr[] = "I Am a Student";
	int i = 0;
	while (arr[i] != '\0')
	{
		if (arr[i] >= 'a' && arr[i] <= 'z')
		{
			arr[i] -= 32;
		}
		i++;
	}
	printf("%s", arr);
	return 0;
}

使用了函数可以简洁一些

#include<stdio.h>
#include<ctype.h>
int main()
{
	char arr[] = "I Am a Student";
	int i = 0;
	while (arr[i] != '\0')
	{
		if (islower(arr[i]))
		{
			arr[i] -= 32;
		}
		i++;
	}
	printf("%s", arr);
	return 0;
}

isalpha函数:

#include<stdio.h>
#include<ctype.h>
int main()
{
	int ret = isalpha('b');//数字是0 小写字母是2,大写字母是1 返回值 这些值是看环境的,其他环境不一定
	printf("%d", ret);
	return 0;
}

 

2.字符转换函数

C语言提供了2个字符转换函数:

1 int tolower(int c);//将传进去的参数大写变成小写

2 int toupper(int c); //将传进去的参数小写变大写

int和char会自动转换在赋值中, 

代码实例:

#include<stdio.h>
#include<ctype.h>
int main()
{
	printf("%c\n", tolower('A'));
	printf("%c", toupper('a'));
	return 0;
}

 

 

3.strlen的使用和模拟实现

1 size_t strlen(const char* str);
1.字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包括'\0')
2.参数指向的字符串必须要有'\0',不然没有结束标志
3.函数的返回值是size_t类型的,用来加减都是正的
4.使用strlen函数需要包含头文件,string.h
因为返回类型是size_t所以俩个无符号的数进行加减也是无符号类型的,无符号类型的是没有负的。
代码实现:
方法一(计数法):
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int my_strlen1(char* p)
{
	int count = 0;
	while (*p != '\0')
	{
		count++;
		p++;
	}
	return count;
}

int main()
{
	char arr[] = "abcdef";//数组是可改变的
    char* p="abcdef"//是常量区的,是不可修改的
	int ret1 = my_strlen1(arr);
	printf("%d", ret1);
	return 0;
}

方法二(地址相减):
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int my_strlen1(char* p)
{
	char* pp = p;
	int count = 0;
	while (*p != '\0')
	{
		p++;
	}
	return p-pp;
}

int main()
{
	char arr[] = "abcdef";
	int ret1 = my_strlen1(arr);
	printf("%d", ret1);
	return 0;
}

地址减去一个地址是俩个地址之间的距离,通过循环让p到字符串的'\0'的位置,尾的地址减去头的地址就是头和尾的距离,也就是个数。

方法三(递归):

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int my_strlen1(char* p)
{
	if (*p == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen1(p + 1);
	}
}

int main()
{
	char arr[] = "abcdef";
	int ret1 = my_strlen1(arr);
	printf("%d", ret1);
	return 0;
}

通过递归的方式,到'\0'就返回0,否则就加一并让p指向下一位,再作为my_strlen函数的参数。

4.strcpy的使用和模拟实现

1 char* strcpy(char* destination,const char* source);
1.source字符串必须以 '\0' 结束(拷贝会到'\0'之前,dest后面有也不会)
2.会将source字符串中的 '\0' 拷贝到目标空间
3.目标空间必须足够大,防止存不下source字符串的大小
4.目标空间还得是可以修改的(如果前面有const则就是不能修改的)
strcpy函数的使用:

会把arr1中的内容覆盖到arr2上。 

strcpy的模拟实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>
char* my_strcpy(char* dest, const char* sre)
{
	assert(dest && sre);防止dest与sre是NULL
	char* ret = dest;
	while (*dest++ = *sre++)当到'\0'时会再赋值一次,然后再判断是否满足循环情况。
		;
	return ret;
}

int main()
{
	char arr1[] = "hello ";
	char arr2[20] = "xxxxxxxxxxx";
	my_strcpy(arr2,arr1);
	printf("%s", my_strcpy(arr2, arr1));
	return 0;
}
*dest++是++优先级高但是因为是后置的所以先解引用,再++但对应的是dest而不是*dest,(*dest)++是对解引的值++,而dest++是把地址向后移一位。通过循环把*sre的值赋给*dest。
所以当sre到'\0'就不会再赋值了,循环结束,printf只打印'\0'前面的数据。

5.strcat的使⽤和模拟实现

1.源字符串必须以'\0'结束
2.目标字符串中也需要有'\0',不然不清楚从那里开始追加
3.目标空间需要足够大才行,能接收追加的大小
4.目标空间必须可以修改
strcat函数的使用:

strcat函数的模拟实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>

char* my_strcat(char* dest, const char* sre)
{
	assert(dest && sre);
	char* ret = dest;
	while (*dest!='\0')//while(*dest++)会到'\0'的下一个位置,不会到'\0'的位置
		dest++;
	while (*dest++ = *sre++)//把\0赋值完后再判断是否为0
		;
	return ret;
}

int main()
{
	char arr1[] = "hello ";
	char arr2[20] = "xxxxxxxxxxx";
	char* ret=my_strcat(arr2,arr1);
	printf("%s",ret);
	return 0;
}

 

会把\0也一起带过去。 

6.strcmp的使用和模拟实现

标准规定:
1.第一个字符串大于第二个字符串,返回大于0的数字
2.第一个字符串等于第二个字符串,返回0
3.第一个字符串小于第二个字符串,返回小于0的数字
判断俩个字符串的大小是通过比较它们ASCII码值的大小

一样的则就相同,不一样的则比较ASCII码值来比较,按照顺序一个一个比下去,只要一个比另外一个大则整个大小就大于另一个,与数量多少无关。 

strcmp函数的模拟实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>

int my_strcmp(char* p1, char* p2)
{
	assert(p1 && p2);
	while (*p1 == *p2)
	{
		if (*p1 == '\0')
		{
			return 0;
		}
		p1++;
		p2++;
	}
	return *p1 - *p2;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abq";
	int ret = my_strcmp(arr1, arr2);
	int r = strcmp(arr1, arr2);
	printf("%d %d", ret,r);
	return 0;
}

先通过循环把相同的排除出去,如果全是相同就返回0,否则就返回俩个不同值的差。

返回值是负的就说明arr1小于arr2,返回值的大小无关,与正负有关,不同的环境可能返回值不一样。

7.strncpy函数的使用

1 char * strncpy ( char * destination, const char * source, size_t num );
这个函数与stcpy的区别是多了一个参数 size_t num,就是选择覆盖多少个字节到目标字符串上,相对来说安全一点,strncpy,strncmp,strncat这三个都是长度受限的字符串函数。

上图可知strcnpy选择拷贝是不会把'\0'给拷贝过去的。

8.strncat函数的使用

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

与strcat函数区别在于可以选择多少个字节追加到后面。

选择追加超过是没关系的,追加会把'\0'给带过去。

9.strncmp函数的使用

1 int strncmp ( const char * str1, const char * str2, size_t num );
与strcmp的区别是选择去比较俩个字符串的大小。

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

1 char* strstr(const char* str1,const char* str2);
函数返回的是str2在str1中第一次出现位置的地址。
strstr函数模拟实现:
首先有三种情况:
第一种情况是复杂的,因为在匹配俩个后,第三个是对不上的,需要重新来过,但是指针已经往下走了,所以需要再来一个指针指向最开始的位置,这样就可以比完之后可以回到最开始的位置,在往下一位继续比对剩下的。
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>

char* my_strstr(const char* p1, const char* p2)
{
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cur = p1;
	while (*cur)
	{
		s1 = cur;
		s2 = p2;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
}
int main()
{
	char arr1[20] = "acddfg";
	char arr2[] = "df";
	char* p = my_strstr(arr1, arr2);
	printf("%s", p);
	return 0;
}

创建临时变量s1和s2来遍历,cur来作为当前位置的变量,如果为匹配可以通过重新赋值回到原来的位置继续访问下面的,返回时需要强制转换一下,因为函数的类型是char*类型,而cur是const char*类型的。

11.strtok函数的使用

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

1.sep参数指向一个字符串,定义了用作分隔符的字符集合(像汉字的逗号,句号类的)

2.第一个参数指定一个字符串,它包含了0后置多个由sep字符串一个孩子多个分隔符分割的标记

3.strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针

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

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

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

例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>

int main()
{
	char arr1[] = "ac#dd%f&g";
	char arr2[20] = { 0 };
	strcpy(arr2, arr1);
	char* ret = NULL;
	const char* sep = "#%&";
	ret = strtok(arr2, sep);
	printf("%s\n", ret);

	ret = strtok(NULL, sep);
	printf("%s\n", ret);

	ret = strtok(NULL, sep);
	printf("%s\n", ret);
	
	ret = strtok(NULL, sep);
	printf("%s\n", ret);
	return 0;
}

12.strerror函数的使用

1 char * strerror ( int errnum );
strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明
的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动
的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应
的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是
有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
例子:
也可以了解⼀下perror函数,perror 函数相当于⼀次将上述代码中的第9⾏完成了,直接将错误信息打 印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
总结:一个是获取错误信息字符串,一个是打印出错误信息。
  • 41
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值