字符函数和字符串函数(1)



🦆 个人主页:深邃-

❄️专栏传送门:《C语言》《数据结构》

🌟Gitee仓库:《C语言》《数据结构》


目录


C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。


字符分类函数

这些函数的使用都需要包含一个头文件是 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 字母或者数字,a-z,A-Z,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

这些函数的使用方法非常类似,我们就讲解一个函数的事情,其他的非常类似:

islower

c 复制代码
int islower ( int c );

注意:传参传的是字符,那为什么这里参数是int c,返回值也是int,因为字符本质上就是整数,字符存储是对应的ASCLL码值
islower 是能够判断参数部分的 c 是否是小写字母的。通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。

c 复制代码
int main()
{
	if (islower('a'))
	{
		printf("是小写\n");
	}
	else
	{
		printf("不是小写\n");
	}
	return 0;
}
  • 写一个代码,将字符串中的小写字母转大写,其他字符不变。
c 复制代码
int main()
{
	char arr[] = "I Am a Chinese.";//'\0' - 0
	//            0123...
	//将字符串中的字符逐个进行处理
	//遇到小写,转换成大写,再输出
	//如果不是小写,正常输出
	int i = 0;
	while (arr[i])
	{
		if (islower(arr[i]))
			arr[i] -= 32;
		printf("%c", arr[i]);
		i++;
	}
	return 0;
}

isdigit

  • 类比
c 复制代码
#include <ctype.h>
int main()
{
	int r = isdigit('4');
	//printf("%d\n", r);
	if (r)
	{
		printf("是10进制的数字字符\n");
	}
	else
	{
		printf("不是10进制的数字字符\n");
	}
	return 0;
}

字符转换函数

tolower,toupper

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

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

上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使用 tolower 函数

c 复制代码
#include<stdio.h>
#include <ctype.h>
int main()
{
	//int r = toupper('a');
	int r = tolower('A');
	printf("%c\n", r);
	return 0;
}
  • 写一个代码,将字符串中的小写字母转大写,其他字符不变。
c 复制代码
//写一个代码,将字符串中的小写字母转大写,其他字符不变。
#include<stdio.h>
#include <ctype.h>
int main()
{
	char arr[] = "I Am a Chinese.";//'\0' - 0
	//            0123...
	//将字符串中的字符逐个进行处理
	//遇到小写,转换成大写,再输出
	//如果不是小写,正常输出
	int i = 0;
	while (arr[i])
	{
		if (islower(arr[i]))
			arr[i] = toupper(arr[i]);
		printf("%c", arr[i]);
		i++;
	}
	return 0;
}
  • 如果正常写,不用库函数 如果正常写,不用库函数 如果正常写,不用库函数
c 复制代码
int main()
{
	char ch = 'w';
	if (ch >= 'A' && ch <= 'Z') //isupper()
	{
		//...
	}
	return 0;
}

strlen的使用和模拟实现

strlen的使用

c 复制代码
size_t strlen ( const char * str );

  • 字符串以 '\0'作为结束标志,strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0')。
  • 参数指向的字符串必须要以 '\0' 结束。
  • 注意函数的返回值为 size_t,是无符号的(易错
  • strlen 的使用需要包含头文件 <string.h>
  • 学会 strlen 函数的模拟实现

错误写法 错误写法 错误写法

无\0

c 复制代码
#include <string.h>

int main()
{
	char arr[3] = { 'a', 'b', 'c' };

	size_t len = strlen(arr);
	printf("%zu\n", len);
	return 0;
}


错误写法 错误写法 错误写法

c 复制代码
#include <string.h>

int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<=\n");
	}
	return 0;
}

因为返回值是size_t类型,-3的补码11111111111111111111111111111101,因为size_t为正数,补码与原码相同,所以只会是一个巨大的数,所以将两个strlen函数放两边即可

strlen的模拟实现

  • 方式一:计数器 方式一:计数器 方式一:计数器
c 复制代码
//计数器⽅式
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}
  • 方式二:指针---指针 方式二:指针---指针 方式二:指针---指针
c 复制代码
#include<stdio.h>
#include <string.h>
#include<assert.h>
//指针-指针的⽅式
int my_strlen(char* s)
{
	assert(s);
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}

递归实现

  • 方式三:递归实现 方式三:递归实现 方式三:递归实现
c 复制代码
//不能创建临时变量计数器
int my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

strcpy的使用和模拟实现

strcpy的使用

c 复制代码
char* strcpy(char * destination, const char * source );
  • Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可修改
  • 学会模拟实现。
  • 返回值是目标地址,可以嵌套调用。
c 复制代码
	arr2 = arr1;//ok?
	因为数组名是地址,数组名是指针常量,地址是常量值,不能被修改
	5 = 3;
	地址是指向空间的,但是地址不是空间

例子 例子 例子

c 复制代码
//strcpy
//string copy
#include <string.h>
int main()
{
	char arr1[] = "hello world";
	char arr2[20] = { 0 };
	char* ret = strcpy(arr2, arr1);
	printf("%s\n", arr2);
	printf("%s\n", ret);
	return 0;
}

错误例子 错误例子 错误例子

  • 目标空间必须可修改
c 复制代码
#include<stdio.h>
#include <string.h>
#include<assert.h>
int main()
{
	char arr1[] = "hello world";
	char* p = "xxxxxxxxxxxxxxxxxxxxx";//常量字符串,不能被修改的-err
	char* ret = strcpy(p, arr1);
	printf("%s\n", p);
	printf("%s\n", ret);
	return 0;
}

char* p = "xxx",p是字符串常量,存储在程序的只读数据段

strcpy的模拟实现

c 复制代码
void my_strcpy(char* dest, const char* src)
{
	//拷贝\0前面的字符
	while (*src != '\0')
	{
		*dest = *src;
		src++;
		dest++;
	}
	*dest = *src;//拷贝\0
}

题⽬出⾃《⾼质量 C / C + + 编程》书籍最后的试题部分,有意思写法 题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分,有意思写法 题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分,有意思写法

c 复制代码
//1.参数顺序
//2.函数的功能,停⽌条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}

这是c语言语法特性,赋值表达式,执行赋值后,整个表达式的值就是被赋值后左操作数的值
在c语言中,有:是语句,无:是表达式,可以放到while,if中
在python中,=是赋值语句,不能当判断条件

strcat的使用和模拟实现

strcat使用

c 复制代码
char * strcat ( char * destination, const char * source );
  • Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
  • 源字符串必须以 '\0' 结束。
  • 目标字符串中也得有 \0,否则没办法知道追加从哪里开始。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 字符串自己给自己追加,如何?

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

strcat模拟实现

c 复制代码
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//1. 目标空间的\0
	while (*dest != '\0')
		dest++;
	//2. 拷贝
	while (*dest++ = *src++)
	{
		;
	}
	return  ret;
}

int main()
{
	char arr1[20] = "hello\0xxxxxxxxxx";
	char arr2[] = "world";
	char* r = my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	printf("%s\n", r);
	return 0;
}
相关推荐
初中就开始混世的大魔王2 小时前
3.1 DDS 层-Core
开发语言·c++·网络协议·tcp/ip·信息与通信
我真不是小鱼2 小时前
cpp刷题打卡记录24——路径总和 & 路径总和II
数据结构·c++·算法·leetcode
菜鸟小九2 小时前
JVM垃圾回收
java·jvm·算法
nianniannnn2 小时前
力扣 347. 前 K 个高频元素
c++·算法·leetcode
x_xbx2 小时前
LeetCode:217. 存在重复元素
数据结构·leetcode·哈希算法
曹牧2 小时前
JDK 1.6 ,无法通过安全套接字层(SSL/TLS)加密建立数据库安全连接
java·开发语言·ssl
漫随流水2 小时前
c++编程:求阶乘和
数据结构·c++·算法
再卷也是菜2 小时前
算法基础篇(13)单调栈
数据结构·c++
Frostnova丶2 小时前
LeetCode 2839. 判断通过操作能否让字符串相等 I
算法·leetcode