字符函数和字符串函数

目录

[1. 字符分类函数](#1. 字符分类函数)

1.1写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变

[1.2 toupper 和 tolower](#1.2 toupper 和 tolower)

[2. strlen 的使⽤和模拟实现](#2. strlen 的使⽤和模拟实现)

[方法1 计数器](#方法1 计数器)

[方法2 指针-指针](#方法2 指针-指针)

[方法3 递归](#方法3 递归)


[3. strcpy 的使⽤和模拟实现](#3. strcpy 的使⽤和模拟实现)

[strcpy 的实现](#strcpy 的实现)

[4. strcat 的使⽤和模拟实现](#4. strcat 的使⽤和模拟实现)

stract的实现

[5 strcmp 的使⽤和模拟实现](#5 strcmp 的使⽤和模拟实现)

strcmp的实现

[6. strncpy 函数的使⽤](#6. strncpy 函数的使⽤)

[7. strncat 函数的使⽤](#7. strncat 函数的使⽤)

[8 . strncmp函数的使⽤](#8 . strncmp函数的使⽤)

[9. strtok 函数的使⽤](#9. strtok 函数的使⽤)

1. 字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使⽤都需要包含⼀个头⽂件是ctype.h

这些函数可以也用来判断返回值

islower 是能够判断参数部分的 c 是否是⼩写字⺟的。

下面写一个练习

1.1写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变

在这里就可以使 islower 来判断 ,代码就可以如下:

#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]))//注 islower的头文件是 <ctype.h>
		{
			arr[i] -= 32;//如果进到这里的话就是小写字母, 小写字母- 32 =大写字母
		}
		i++;
	}
	printf(" %s ", arr);
	return 0;
}

这样的话就完成了,

1.2 toupper 和 tolower

下面给大家介绍两个小写转大写字符,大写转 小写字符

#include <stdio.h>
#include <ctype.h>
int main()
{
	char ch = toupper('e');// 小写字符转为大写字符 头文件也是<ctype.h>
	printf("%c\n", ch);
	char c = tolower('E');//大写字符转换成小写字符,字符串不可以转换
	printf("%c\n", c);

		return 0;

toupper 是小写字符转换为大写字符。

tolower 是大写字符转换成小写字符

字符串不可行,别问我为什么知道。

那么例题1就可以优化了,

#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]))//注 islower的头文件是 <ctype.h>
		{
			arr[i]=toupper(arr[i]);
		}
		i++;
	}
	printf(" %s ", arr);
	return 0;
}

2. strlen 的使⽤和模拟实现

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

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

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

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

#incldue <stdio.h>
#include <string.h>
int main()
{
	if (strlen("abc") - strlen("abcde")>0)//大家认为第一个strlen里面三个字符减去第二个strlen里面6个字符等于-3 ,
		//所以就选了=<  其实不是的,因为strlen的返回值是size_t 它是无符号整形,因为-3的补码如果是3他的补码很大的
	{
		printf("> ");
	}
	else
	{
		printf("=< ");
	}


	return 0;
}

前面学过的strlen的实现,忘记了的可以在回归也一下

方法1 计数器

#include <stdio.h>
#include <assert.h>
int  my_strlen( const char * arr)
{
	int count = 0;
	assert(arr != NULL);

	while (*arr != '\0')
	{
		count++;
		arr++;
	}
	return count;
 }
int  main()
{
	char arr[] = "abcd";
	size_t len = my_strlen(arr);
	printf("%zd ", len);
	return 0;
}

方法2 指针-指针

这两种方法都是前面讲到的

#include <stdio.h>
#include <assert.h>
int  my_strlen(const char* arr)
{
	const char* start = arr;
	assert(start != NULL);
	while (*start != '\0')
	{
		start++;
	}
	return  start-arr;
}
int  main()
{
	char arr[] = "abcd";
	size_t len = my_strlen(arr);
	printf("%zd ", len);
	return 0;
}

下面还有第三种方法:

方法3 递归

大家先看这张图,再去理解下面的代码,

#include <stdio.h>
int  my_strlen(const char* arr)
{
	if (*arr != '\0')
		return 1 + my_strlen(arr + 1);//第一个不是0 最少就打印一位也就是 a ,
	//然后在调用 如何找到b 就是首个元素+1 --> arr+1 这样直到找到 \0 
	else//如果第一位为0 就返回0
		return 0;
}

int  main()
{
	char arr[] = "abcd";
	size_t len = my_strlen(arr);
	printf("%zd ", len);
	return 0;
}

3. strcpy 的使⽤和模拟实现

1 char* strcpy(char * destination, const char * source );

源字符串必须以 '\0' 结束,没有\ 0 strcpy无法结束。

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

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

• ⽬标空间必须可修改。

#include <stdio.h>

#include <string.h>
int main()
{
char arr1[20] = {0};
char arr2[] = "ao li gei !";
strcpy(arr1, arr2);
printf("%s ", arr2);

return 0;
}

这样就将源头字符串 arr 2拷贝到到了目的字符串 arr 1

打开调试可以清楚的看见

这里真的变成了 \0

strcpy 的实现

strcpy实现大概思路是 将arr1 的内容赋值给arr2 的内容

#incldue<stdio.h>
#include <string.h>
#include <assert.h>
void my_strcpy(char* dest, const char* src)//const char*src 来限制src的不能被修改
{
	assert(dest && src);

        while (*src != '\0')
	{
		*dest = *src; //将src的内容放置到dest空内容里
		dest++;
		src++;
	}
	*dest = *src;//来到这里说明 src不满足 while循环也就是等于 \0 的时候
}

int main()
{
	char arr1[] = "sit down";
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s ", arr2);
	return 0;

当然代码也可以优化。

#include  <stdio.h>
#include <string.h>
#include <assert.h>
void my_strcpy(char* dest, const char* src)//const char*src 来限制src的不能被修改
{
	assert(dest && src);
	while (*dest++ = *src++)//拷贝过去后的字符串,判断表达式,当拷贝到 \ 0 的时候,跳出循环
	{
		;
	}
	*dest = *src;//来到这里说明 src不满足 while循环也就是等于 \0 的时候
}

int main()
{
	char arr1[] = "sit down";
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s ", arr2);
	return 0;
}

4. strcat 的使⽤和模拟实现

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

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

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

• ⽬标空间必须可修改。

• 字符串⾃⼰给⾃⼰追加,如何?不保障

这个代码是strcat的用法,将一个字符串拼接到另一个字符串

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[30] = "hello ";//这里要保证字符串能放下,尽量写的大写,否者就会报错
	char arr2[10] = "world";
	strcat(arr1, arr2);
	printf("%s ", arr1);

	return 0;
}

stract的实现

第一部先把dest存储到ret'中 ,找到目标字符串的 \ 0, 再将源字符串拷贝到目的字符串

#incldue <stdio.h>
#include <assert.h>
char my_stract(char* dest, const char* src)
{
	//1 .找到目标空间的 \0
	char* ret = dest;
	assert(dest && src);
	while (*dest != '\0')
		dest++;
	//2.把原字符串拷贝到目标字符串上
	while (*dest++ = *src++)
		;
return ret;
 }
int main()
{
	char arr1[30] = "hello ";
	char arr2[10] = "world";
	my_stract(arr1,arr2);
	printf("%s ", arr1);
	return 0;
}

5 strcmp 的使⽤和模拟实现

第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字 ◦

第⼀个字符串等于第⼆个字符串,则返回0 ◦

第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字 ◦

那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

strcmp的实现

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* arr1, const char* arr2)
{
	assert(arr1 && arr2 != NULL);
	while (arr1 == arr2)//当arr1 和arr2 相等的时候向后找,
	{
		if (arr1== '\0')//进到这里说明是arr1和arr2 相等, 所以其中一个等于 \0就返回 0
		{
			return 0;
		}
		arr1++;
		arr2++;
	}
	return  arr1 - arr2;// 如果arr1 大于arr2 返回大于0 的数,如果arr1 小于arr2 返回小于零的数
 }
int main()
{
	char arr1[10] = "abcde";// 这里arr1小于arr2 返回小于0 的数
	char arr2[10] = "abcf";
	 int ret =	my_strcmp(arr1, arr2);
	 printf("%d ", ret);

	return 0;

返回了小于0 的数

6. strncpy 函数的使⽤

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

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

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

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "abcd";
	char arr2[20] = "xxxxx";
	strncpy(arr1, arr2, 3);
	printf("%s ", arr1);
	return 0;
}

7. strncat 函数的使⽤

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

Appends the first num characters of source to destination, plus a terminating null-character. (将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字 符)。

• If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.(如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾)。

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "abcd";
	char arr2[20] = "efght";
	strncat(arr1, arr2, 3);
	printf("%s ", arr1);
	return 0;
}

和strcat 相似,就是多加了限制条件

8 . strncmp函数的使⽤

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

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

代码如下:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "abcd";
	char arr2[20] = "abcf";
	 int ret =	strncmp(arr1, arr2, 4);
	 printf("%d ", ret);//前面比后面小就返回小于0 的数
	return 0;
}

9. strtok 函数的使⽤

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

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

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

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

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

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

代码如下:

#incldue <stdio,h>
#include <string.h>
int main()
{
	char arr[] = "zhengpengwei@qq.com";
	char buf[200] = { 0 };
	strcpy(buf, arr);//拷贝一份临时的字符串来切割
	char* set = "@.";//分割的符号
	char* ret = NULL;
	for (ret =strtok(buf, set); ret  != NULL; ret =strtok(NULL, set))//第一次传完 buf后
//面可以使用NULL ,因为这次的NULL自动存储了上一次的buf ,
	{
		printf("%s \n", ret);

	}
	return  0;
}

完结 今天又是写了一天

相关推荐
Sheep Shaun4 分钟前
希尔排序和直接插入排序
c语言·数据结构·算法·排序算法
静能生慧20 分钟前
倪师学习笔记-天纪-斗数简介
笔记·学习·倪师·玄学
小林熬夜学编程28 分钟前
【Linux系统编程】第三十弹---软硬链接与动静态库的深入探索
服务器·c语言·开发语言·前端·c++·算法
楠了个难39 分钟前
RGB转HDMI方案、MS7210驱动——FPGA学习笔记20
笔记·学习·fpga开发
冉佳驹1 小时前
数据结构 ——— 单链表oj题:相交链表(链表的共节点)
c语言·数据结构·算法·链表
f狐0狸x1 小时前
用C语言实现一些常见的库函数
c语言
姚杰献2 小时前
股市入门常见术语介绍
笔记·金融·web3·区块链·程序员创富
rachel_wanna_die2 小时前
【深圳大学】大学物理实验2 双光栅测微振动预习题参考
笔记
Pandaconda2 小时前
【计算机网络 - 基础问题】每日 3 题(三十四)
开发语言·经验分享·笔记·后端·计算机网络·面试·职场和发展