C:字符函数与字符串函数-学习笔记

目录

1、字符分类函数

2、字符转换函数

3、字符串函数

[4、strlen 函数的使用与模拟实现](#4、strlen 函数的使用与模拟实现)

[4.1 strlen函数的使用](#4.1 strlen函数的使用)

[4.2 strlen函数的模拟实现](#4.2 strlen函数的模拟实现)


1、字符分类函数

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 | 字母a~z或A~Z |
| isalnum | 字母或数字,a~z,A~Z,0~9 |
| ispunct | 标点字符,任何不属于数字和字母的图形字符(可打印) |
| isgraph | 任何图形字符 |
| isprint | 任何可打印字符,包括图形字符和空白字符 |

由于字符分类函数较多,且这些函数的使用方式也都相同,因此在这里小编就只对其中某一些进行介绍来帮助大家简单了解一下这些函数的使用方式,如果想要对它们有更详细的了解,可以进入c++官网查看,点击上面表格中函数名即可!

我们怎么判断输入的字符是小写字符还是大写字符呢?这里就可以使用到 islowerisupper这两姐妹了。

我们来看cplusplus 对妹妹 islower 的介绍:

从上图中我们能得到什么信息呢?islower的作用是判断输入字符是否为小写字母,并通过返回值告诉我们结果,如果是小写字母 ,则返回值为非零值 ,如果不是小写字母 ,则返回值是0。

接下来小编将用代码来带大家深入了解islower的作用及使用方式。

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

由于A不是小写字母,所以我们得到的返回值是0。

那我们可以怎么使用 islower 这个函数呢?

#include <stdio.h>
#include <ctype.h>
int main()
{
	int ret = islower('A');
	//printf("%d\n", ret);
	if (ret)
		printf("小写");
	else
		printf("大写");
	return 0;
}

为什么这么写呢?如果Islower判断的字符是大写,则会返回0,0为假,则执行else语句。

如果输入的是小写字母

如果我们想判断是否为数字字符该怎么办,可以使用 isdigit 函数

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

如果它是数字字符的话,会返回非零值,如果是数字字符的话,会返回0,我们来判断一下

其它的字符分类函数使用方式皆是如此,因此就不一一介绍了。

这些函数也是可以组合使用的,可以根据个人情况来使用。

**练习:**写一个函数,将字符串中的小写字符转大写,其它字符不变。

字符串"Hello China",将里面的小写字符都转为大写。

int main()
{
	char arr[20] = "Hello China";
	//下标i         01234567......  
	//遍历数组arr
	int i = 0;
	while (arr[i])//这里条件是arr[i]是因为字符串末尾有\0,当遍历到\0的时候,0为假,循环结束
	{
		if (islower(arr[i]))
		{
			//小写字母与大写字母的ASCLL值对应位置相差32
			//a-97 A-65
			arr[i] = arr[i] - 32;
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}

这里就完成了,这也就是islower函数的具体应用。

不过呢!接下来我们将学习两个函数来帮助我们进行大小写字母的转换

2、字符转换函数

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

int tolower(int c);//将参数传进去的大写字母转小写
int toupper(int c);//将参数传进去的小写字母转大写

在前面我们的那道例题中,我们将小写转大写是借助了ASCLL值大小写字母相差32的特点来转换的,但是有了字符转换函数,我们就可以直接使用toupper函数了。

int main()

{

char arr[20] = "Hello China";

int i = 0;

while (arr[i])

{

if (islower(arr[i]))

{

arr[i] = toupper(arr[i]);

}

i++;

}

printf("%s\n", arr);

return 0;

}

到这里我们也就介绍清楚字符分类函数和字符转换函数了。关于这些函数,只有多多练习,才能够掌握的更加牢靠。

3、字符串函数

字符串函数有strlen,strcpy,strcat,strcmp,strncpy,strncat,strncmp,strstr,strtok,strerr共十个函数,我们将这十个函数分为四类。

接下来会分别介绍。这些函数所需要的头文件是string.h

4、strlen函数的使用与模拟实现

4.1 strlen函数的使用

sizt_t strlen(const char* str);

关于strlen函数,想必大家应该不会很陌生吧!虽然没有系统的介绍过这个函数,但是这个函数在小编前面的文章中也是多次出现,算是老熟人了。这次会带大家详细了解一下这个函数。

该函数的类型是size_t,参数是字符串str,返回值是字符串的长度。

那么该函数该怎么使用呢?

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "abcdef";
	size_t len = strlen(arr);
	printf("%zd\n", len);
	return 0;
}

我们可以得到字符数组arr的长度通过strlen函数

对于size_t类型的数据,打印使用 %zd 占位符。

这就是strlen函数的作用,它可以求一个字符串长度,并返回一个值来表示。

strlen函数的工作原理是什么呢?

我们知道字符串"abcdef"中放着a b c d e f \0字符

arr是数组名,数组名表示首元素地址,也就是说我们从首元素地址开始传字符给strlen;

因此这里strlen(arr)统计的是从首元素到 \0之前的字符个数,所以这里返回的结果是6。

所以我们可以知道strlen函数的工作原理是---从给定的起始位置开始,向后统计\0之前的字符个数。

这里为什么说是从给定的起始位置开始统计呢?

我们可以来测试一下

int main()
{
	char arr[] = "abcdef";
	size_t len = strlen(arr+1);
	printf("%zd\n", len);
	return 0;
}

arr表示的是数组首元素地址,那么arr+1则表示第二个元素的地址。

我们可以看到此时返回的结果就是5,所以说起始位置很重要。strlen函数统计字符串的长度是从给定的起始位置开始统计,直到遇到'\0'。

注意:strlen函数的返回值位size_t,是无符号的

来看下面这个例子,该代码的输出结果是什么?

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

上面例子中,我们可以知道字符串arr1的长度是6,字符串arr2的长度是3,根据数学上来说,该代码最后输出的应该是 < 号,来看一下结果

这里为什么会输出 > 号呢?

这是因为strlen(arr2) 的返回值是size_t, strlen(arr1)的返回值也是size_t,这样我们得到的结果也是size_t类型,从数学上3 - 6 我们得到的是-3,size_t是无符号类型

-3的原码是:10000000000000000000000000000011

反码是: 111111111111111111111111111111111100

补码是: 111111111111111111111111111111111101

由于size_t是无符号类型,所以当我们把-3存入内存中的时候,-3的补码的首位就不会被认为是符号位,既然如此,111111111111111111111111111111111101就是一个非常大的正数。这个数肯定会大于0,所以最终打印出来的结果是 >

我们如何才能比较这两个的大小呢?

直接将两个数进行相比即可 if (strlen(arr2) > strlen(arr1) )

如果非要相减进行比较,就可以使用强制类型转换,将它两转换成int类型。

4.2 strlen函数的模拟实现

int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	return 0;
}

关于这个返回类型为什么使用size_t,可能有些人会有些疑惑,这里统一说一下,由于strlen函数是求字符串函数的长度的,返回值用来表示字符串的长度,既然是表示长度的,那么就不可能会是负数,因此,这里使用size_t会更加合适。

size_t my_strlen(const char* str)

这里我们不希望str能够改变所要求长度的字符串,因此使用const修饰一下。

接下来使用两种方式来模拟实现strlen函数。

1- 计数器

#include <stdio.h>
#include <string.h>
#include <assert.h>
size_t my_strlen(const char* str)
{
	size_t count = 0;
	assert(str != NULL);//防止是空指针
	while (*str)//这里*str作为条件是因为最终会读取到\0终止循环
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

2- 指针- 指针

#include <stdio.h>
#include <string.h>
#include <assert.h>
size_t my_strlen(const char* str)
{ 
    char* start = str;// 记录字符串的起始位置
    assert(str != NULL);
 
    while (*str)
    {
        str++;
    }
    return str - start; // 通过当前指针位置减去起始位置得到字符串的长度
}
int main()
{
    char arr[] = "abcdef";
    size_t len = my_strlen(arr);
    printf("%zd\n", len);
    return 0;
}

3-递归

关于递归,我们首先想到的便是大事化小

那什么叫大事化小呢?

代码实现:

#include <stdio.h>
#include <string.h>
#include <assert.h>
size_t my_strlen(const char* str)
{ 
    if (*str == '\0')//如果开始就是\0,则说明该字符串长度为0
        return 0;
    else
        1 + my_strlen(str + 1);
}
int main()
{
    char arr[] = "abcdef";
    size_t len = my_strlen(arr);
    printf("%zd\n", len);
    return 0;
}

**结语:**本篇文章到这里就结束了,下一篇文章将会介绍完所有的字符串函数,期待大家的到来!!!

相关推荐
xiaoyalian2 小时前
R语言绘图过程中遇到图例的图块中出现字符“a“的解决方法
笔记·r语言·数据可视化
Red Red3 小时前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
贰十六4 小时前
笔记:Centos Nginx Jdk Mysql OpenOffce KkFile Minio安装部署
笔记·nginx·centos
知兀4 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
Natural_yz5 小时前
大数据学习17之Spark-Core
大数据·学习·spark
qq_172805595 小时前
RUST学习教程-安装教程
开发语言·学习·rust·安装
一只小小汤圆5 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
醉陌离5 小时前
渗透测试笔记——shodan(4)
笔记
虾球xz6 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
LateBloomer7776 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos