字符函数和字符串函数

一.字符函数

1.字符分类函数

在这里插入图片描述
这些函数都是字符分类函数,他们的使用都很类似,就是用于判断一个字符的类型。需要包含头文件<ctype.h>,参数类型是整型(字符的ascall值),返回类型也是整型,如果满足就返回非0值,否则返回0。
接下来我们就举例说明:

int main() {
	int a = 0;
	a = isupper('a');
	printf("%d\n", a);
	return 0;
}

2.字符转换函数

c语言提供了两种字符转换函数,也要包含头文件<ctype.h>如下:参数和返回类型都是字符的ascall值,但实际我们传参时传字符就行。
在这里插入图片描述
如果tolower传小写字符,那么就不会转换。
举例:

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

3.运用字符函数

写一段代码,将字符串中的小写字母转为大写字母,其他字符保持不变。

int main() {
	char arr[] = "I Love You";
	int i = 0;
	while (arr[i]) {
		if (arr[i] >= 'a' && arr[i] <= 'z') {
			arr[i] -= 32;
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}

改进后:

int main() {
	char arr[] = "I Love You";
	int i = 0;
	while (arr[i]) {
		if (islower(arr[i])) {
			arr[i]=toupper(arr[i]);//!!!注意:这里字符转换upper函数只是将小写字符转换为大写,但是数组中原来的字符并没有改变。
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}

二.字符串函数

使用时都要包含头文件<string.h>

1.strlen函数

size_t strlen(char* p);
计算字符串长度,统计的是从p开始,\0以前的字符个数。
p指向的字符串必须包含\0.
strlen函数的返回类型出错点:

#include <string.h>
int main() {
	char arr1[] = "abc";
	char arr2[] = "abcdef";
	if (strlen(arr1) - strlen(arr2) > 0) {
		printf("arr1>arr2\n");
	}
	else
		printf("arr1<=arr2\n");
	return 0;
}

这是因为两个sizez_t类型的数相减,结果也是size_t类型的,-3的符号位应该就作为数值位看待,是个特别大的无符号整数,所以结果是>。
strlen函数的模拟实现:
第一种——计算器

size_t my_strlen(char* arr) {
	int i = 0;int count = 0;
	while (arr[i]) {
		count++;
		i++;
	}
	return count;
}
int main() {
	char arr[] = "abcdef";
	size_t len=my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

第二种——指针-指针

size_t my_strlen(char* arr) {
	int i = 0;
	char* p = arr;
	while (arr[i]) {
		p++;
		i++;
	}
	return p - arr;
}
int main() {
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

第三种——递归

size_t my_strlen(char* arr) {
	if (*arr == '\0')
		return 0;
	else
		return 1 + my_strlen(arr + 1);
}
int main() {
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}


2.strcpy函数

char* strcpy(char dest,const char src);
返回的是目标空间的首地址。
第一个参数是目标空间的首地址,第二个参数是源字符串。
功能是将src指向的字符串拷贝到dest指向的空间中。
注意:src指向的字符串必须有\0,
而且拷贝的时候也要拷贝\0,
目标空间必须足够大,可以装下源字符串,而且要可以修改。
strcpy函数的使用和模拟:

char* my_strcpy(char* dest, const char* src) {
	while (*src) {
		*dest = *src;
		dest++;src++;
}
	*dest = *src;
	return dest;
}
int main() {
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };
	char* p=my_strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

代码改进:

#include <assert.h>
char* my_strcpy(char* dest, const char* src) {
	assert(dest && src);
	while (*dest++ = *src ++) {//将表达式放在这里,可以让\0也copy给*dest
	             ;//虽然++的优先级高于*,但是先使用后++,相当于*dest=*src,dest++,src++;
	}
	return dest;
}
int main() {
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };
	char* p = my_strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}


3.strcat函数

char* strcat(char* dest,const char* src);
返回的是目标空间的首地址,第一个参数是目标空间的首地址,第二个参数是源字符串。
注意:源字符串必须有\0,否则不知道从哪里追加字符串结束。
目标字符串也必须有\0,否则不知道从哪里开始追加。
\0也要追加进去目标空间。
目标空间要足够大而且可修改。
strcat函数的使用和模拟:

#include <assert.h>;
char* my_strcat(char* dest, const char* src) {
	char* ret = dest;//注意:dest在后面一直会++,不再是目标空间的首地址。
	assert(dest&&src);
	//先找目标空间中的\0
	while (*dest) {
		dest++;
	}
	//再开始追加,本质就是字符串的拷贝
	while (*dest++ = *src++) {
		           ;
	}
	return ret;
}
int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world";
	char* p=my_strcat(arr1, arr2);
	printf("%s\n", p);
	return 0;
}

4.strcmp函数的使用和模拟

int strcmp(const char* arr1,const char* arr2);
若arr1>arr2,返回大于0的数,arr1==arr2,返回2,否则,返回小于0的数。
这里字符串比较的是相应位置的字符的ascall值。
strcmp函数的使用和模拟:

#include <assert.h>
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;
}
int main() {
	char arr1[] = "abcdef";
	char arr2[] = "abqdef";
	int a=strcmp(arr1, arr2);
	printf("%d\n", a);
	return 0;
}

上面的三个字符串函数是长度不受限制的字符串函数,是不安全的,接下来学习长度受限制的字符串函数,相对来说比较安全。

5.strncpy函数

char* strncpy(char* dest,const char* src,size_t num);
这个函数在拷贝时:
如果num指定的长度小于src的长度,拷贝时不会拷贝\0,让我拷贝几个就拷贝几个字符。
如果num指定的长度大于src的长度,那么就用\0补,直到补齐为止。
strncpy函数的使用:

int main() {
	char arr1[] = "abcdef";
	char arr2[20] = "xxxxxxxxxx ";
	char* p=strncpy(arr2, arr1, 3);
	printf("%s\n", p);
	return 0;
}

6.strncat函数

char* strncat(char* dest,const char* src,size_t num);
strncat函数在追加字符串时:
如果num指定的长度小于src的长度,拷被之后还要追加\0。
如果num指定的长度大于src的长度,拷贝也要追加\0,但是有几个追加几个,不用\0补齐。
strncat函数的使用:

int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world";
	char* p=strncat(arr1, arr2,3);
	printf("%s\n", p);
	return 0;
}

7.strncmp函数

int strncmp(const char* arr1,const char* arr2,size_t num);
strncmp函数的使用:

int main() {
	char arr1[] = "abcdef";
	char arr2[] = "aqc";
	int a= strncmp(arr1, arr2, 3);
	printf("%d\n", a);
	return 0;
}

8.strstr函数

char* strstr(const char* arr1,const char* arr2);
strstr函数返回的是在arr1中第一次出现arr2指向字符串的位置。找不到返回NULL;
strstr函数的使用和模拟:
注意返回时const char* 和char* 类型的统一。

#include <assert.h>
char* my_strstr(const char* str1, const char* str2) {
	assert(str1 && str2);
	const char* cur = str1;//需要一个变量专门记录开始匹配的位置,也就是arr2指向的字符串第一次出现在arr1指向字符串中的位置。
	const char* s1 = NULL;//还需要两个变量记录两个指针刚开始的位置
	const char* s2 = NULL;
	if (*str2 == '\0') {
		return (char*)str1;
	}
	while (*cur!='\0') {
		s1 = cur;
		s2 = (char*)str2;
		while(*s1&&s2&&*s1 == *s2) {
			s1++;
			s2++;
		}
		if (*s2 == '\0') {
			return (char*)cur;
		}
		cur++;
	}
	return NULL;
}
int main() {
	char arr1[] = "abcdefbcdef";
	char arr2[] = "bcd";
	char* p=my_strstr(arr1, arr2);
	printf("%s\n", p);
	return 0;
}

9.strtok函数

char* strtok(char* str,const char* p);
这个函数用于将一个被分隔符分隔开的字符串中的每个字符段提取出来,第一次调用的时候,第一个参数传被分隔开的字符串的首地址,之后传NULL 就行。
第二个参数指向一个字符串,定义的是被当做是分隔符的字符集合,不分先后顺序,齐了就行。
每一次调用会将字符段后面的分隔符变成\0,然后返回字段的首地址,之后记录这个字段的结束地址,之后调用就会从这个被记录的地址后面开始查找,所以后面调用时第一个参数传NULL就行。
如果找不到字段了,返回NULL。
这个函数真的会改变字符串内容,一般第一个参数传递的都是拷贝过来的字符串。
strtok函数的使用和模拟:

int main() {
	char arr[] = "abcd@bbb.de";
	char* p = "@.";
	char* ret = NULL;
	ret=strtok(arr,p);
	printf("%s\n", ret);
	ret = strtok(NULL, p);
	printf("%s\n", ret);
    ret = strtok(NULL, p);
	printf("%s\n", ret);
	return 0;
}

改进:

int main() {
	char arr[] = "abcd@bbb.de";
	char arr2[20] = { 0 };
	strcpy(arr2, arr);
	char* p = "@.";
	char* ret = NULL;
	for (ret = strtok(arr2, p);ret != NULL; ret = strtok(NULL, p)) {
		printf("%s\n", ret);
}
	
	return 0;
}

10.strerror函数

char* strerror(size_t num);
这个函数是用来将参数中的错误码转换成错误信息的,返回的是错误信息的字符串首字符的地址。
c语言和其他系统规定了对应错误码的错误信息放在头文件<errno.h>中,并且在程序运行时创建了一个全局变量errno,初始化为0,当库中的函数在使用时出错,则库函数会主动将错误码存储在errno中。
strerror函数的使用:

int main() {
	for (int i = 0;i <= 10;i++) {
		printf("%s\n", strerror(i));
	}
	return 0;
}


#include <errno.h>
int main() {
		printf("%s\n", strerror(errno));
	return 0;
}

perror函数:
是printf函数和strerror函数的组合,有能力直接打印错误信息,参数是指向字符串指针变量。

int main() {
	perror("cru");
	return 0;
}

先打印字符串,然后打印:和空格,最后打印错误信息。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值