C语言快速入门之字符函数和字符串函数

一.字符分类函数和字符转换函数

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

#include <ctype.h>

以下是具体函数:

这些函数的使用方法类似,我们写出一些代码来举例。

例如,我们实验以下islower()函数,它是接受一个字符,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。

int main()
{char a = 'a';char b = 'Q';char c = '5';printf("%d\n", islower(a));printf("%d\n", islower(b));printf("%d\n", islower(c));return 0;
}

现在,我们写出一个代码,将字符串中的小写字母转大写,其他字符不变

int main()
{char arr[] = "Hello World";printf("%s\n", arr);int con = strlen(arr);int i = 0;for (i = 0; i < con; i++){if (islower(arr[i])){arr[i] -= 32;}}printf("%s\n", arr);return 0;
}

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

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

上面的代码中,我们进行的转换是利用ASCII码,现在我们也可以利用转换函数来更改啦

int main()
{char arr[] = "Hello World";printf("%s\n", arr);int con = strlen(arr);int i = 0;for (i = 0; i < con; i++){if (islower(arr[i])){arr[i] = toupper(arr[i]);}}printf("%s\n", arr);return 0;
}

二.字符串函数

1.strlen的使用和模拟实现

strlen是计算字符串长度的函数,以'\0'为结束,返回一个无符号整型size_t,使用时需要包含头文件string.h

现在我们来模拟实现strlen函数吧

int My_strlen(const char* arr)
{int count = 0;	//计数assert(arr != NULL);	//断言,防止出错while (*arr != '\0'){count++;arr++;}return count;
}

这是最常规的方法,那么,我们能否不创建额外的变量来实现strlen函数呢?这需要运用到函数的递归

int My_strlen_unint(char* arr)
{assert(arr != NULL);if (*arr == '\0')return 0;elsereturn 1 + My_strlen_unint(arr+1);}

2.strcpy的使用和实现

这会把一个字符串拷贝到另一个字符串中,然后返回字符串首元素地址

int main()
{char arr1[] = "hello bit";char arr2[20] = "xxxxxxxxxxxxxxx";char* p = "xxxxxxxxxxxxxxxxxxxxxxx";	//常量字符串,不能更改my_strcpy(arr2,arr1);printf("%s\n", arr2);return 0;
}

使用方式中,arr1是拷贝内容,arr2是更改的字符串,需要注意,我们在定义时不能是常量的字符串,目的地必须要足够大来存放内容且可以更改,同时,    原字符串要有\0,会把原\0拷贝过来

现在我们来模拟实现吧

char* my_strcpy(char* dest, const char* src)
{char* ret;assert(dest && src);//拷贝\0之前的内容while (*dest++ = *src++){;}*dest = *src;	//拷贝\0return ret;
}

3.strcat的使用和模拟

它的作用是来连接字符串

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

他会把arr2放在arr1的后面,最后返回arr2的地址,需要注意的是:源字符串必须以 '\0' 结束。 ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。⽬标空间必须可修改。

现在我们来模拟实现吧。

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

但是,我们如果是自己给自己追加,例如:

int main1()
{char arr1[20] = "abcdef";my_strcat(arr1, arr1);printf("%s\n", arr1);	return 0;
}

上述的代码就会出错,实际是导致了死循环,使得程序崩溃,我们写的只是参考代码

4.strcmp的使用和模拟

strcmp是实现两个字符串的比较,一般来说,两个字符串是不能比较大小的,例如:

char arr1[] = "abcdef";
char arr2[] = "abcdef";
if (arr1 == arr2)	//不正确的,这里比较的是地址
{}if ("abcdef" == "abc")	//这样也是不正确的,比较的也是地址
{}

这两个if都是不正确的,因为他们传入的是地址,比较没有意义

如果要比较两个字符串的内容,需要使用strcmp,会依次来进行比较,最后,函数返回值类型为int,前者大>0,后者大<0,相等返回0

//函数返回值为int,前者大>0,后者大<0,相等返回0
char arr1[] = "abcdef";
char arr2[] = "abq";
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);

现在,我们来模拟实现吧

int my_strcmp(const char* arr1,const char* arr2)
{assert(arr1 && arr2);while (*arr1 == *arr2){arr1++;arr2++;}return *arr1 - *arr2;
}

5.strncpy strncat strncmp

strcpy strcat strcmp 是长度不受限制的字符串函数

strncpy strncat strncmp是长度受限制的字符串函数

int main()
{char arr1[] = "abcdef";char arr2[20] = "xxxxxxxxxxxxxx";strncpy(arr2, arr1, 4);printf("%s\n", arr2);strncpy(arr2, arr1, 8);printf("%s\n", arr2);//把n个字符拷贝过去,如果不够,补足\0return 0;
}
int main()
{char arr1[] = "abcdef";char arr2[20] = "xx\0xxxxxxxxxxx";strncat(arr2, arr1, 8);printf("%s\n", arr2);//把n个字符追加过去,后面会再加一个\0,如果不够,就不管了return 0;
}
int main()
{char arr1[] = "abcdef";char arr2[] = "abqedfss";int ret = strncmp(arr1, arr2, 6);printf("%d\n", ret);return 0;
}

6.strstr的使用和模拟

在一个字符串str1中查找另一个字符串str2是否出现过,如果出现,返回第一次str2出现的位置,如果没出现,返回空指针

例如:

int main()
{char arr1[] = "this is an apple\n";const char* p = "is";const char* p2 = "appl";char* ret = strstr(arr1, p);char* ret2 = strstr(arr1, p2);printf("%s\n", ret);printf("%s\n", ret2);return 0;
}

有时候,我们不一定能找到,

int main()
{char arr1[] = "abbcdefg";char arr2[] = "bcde";char* ret = my_strstr(arr1, arr2);if (ret == NULL)printf("找不到\n");elseprintf("%s\n", ret);return 0;
}

现在,我们来模拟实现吧

char* my_strstr(const char* arr1, const char* arr2)
{const char* s1 = NULL;const char* s2 = NULL;const char* cur = arr1;if (arr2 == '\0')return (char*)arr1;while (*cur){s1 = cur;s2 = arr2;while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return (char*)cur;cur++;}return NULL;
}

7.strtok的使用

提取出由分隔符分隔的串    char* strtok(char* str,const char* sep);str是指定的一个字符串,包含了0个或多个由sep字符串中的一个或多个做分隔符分割的标记

int main8()
{char arr[] = "xianyu@qq.com";char arr2[20] = { 0 };strcpy(arr2, arr);		//会更改字符串	xianyu\0qq\0comconst char* sep = "@.";char* ret = NULL;ret	= strtok(arr, sep);printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);return 0;
}

同时,我们也可以利用循环来实现

int main8()
{char arr[] = "xianyu@qq.com";char arr2[20] = { 0 };strcpy(arr2, arr);		//会更改字符串	xianyu\0qq\0comconst char* sep = "@.";char* ret = NULL;for (ret = strtok(arr, sep); ret != NULL; ret = strtok(NULL,sep)){printf("%s\n", ret);}return 0;
}

8.strerror函数的使用

int main()
{//fopen以只读的方式打开文件,文件不存在,打开失败FILE* pf = fopen("test.txt", "r");if (pf == NULL){printf("%s\n", strerror(errno));perror("zhangsan");//perror有能力直接打印错误信息,先打印传给perror的字符串,:空格,再打印错误码return 1;}fclose(pf);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/274782.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神经网络线性量化方法简介

可点此跳转看全篇 目录 神经网络量化量化的必要性量化方法简介线性对称量化线性非对称量化方法神经网络量化 量化的必要性 NetworkModel size (MB)GFLOPSAlexNet2330.7VGG-1652815.5VGG-1954819.6ResNet-50983.9ResNet-1011707.6ResNet-15223011.3GoogleNet271.6InceptionV38…

【力扣精选算法100道】——二进制求和

LCR 002. 二进制求和 - 力扣&#xff08;LeetCode&#xff09; 目录 &#x1f388;了解题意 &#x1f388;算法分析 &#x1f6a9;cur1>0 &#x1f6a9;cur2>0 &#x1f6a9;t &#x1f388;实现代码 &#x1f388;了解题意 遵循二进制加法法则&#xff0c;如果俩…

单通道 6 阶高清视频滤波驱动电路芯片D1675,一款高清视频信号译码、编码的滤波器和缓冲器

1、概述&#xff1a; D1675单电源工作电压为2.5V到5V&#xff0c;是一款高清视频信号译码、编码的滤波器和缓冲器。与使用分立元件的传统设计相比&#xff0c;D1675更能节省PCB 板面积&#xff0c;并降低成本以及提高视频信号性能。D1675集成了一个直流耦合输入缓冲器、一个消除…

一分钟就能搞定发成绩这件事,你信吗?

快节奏的现代教育环境中&#xff0c;每一分钟都显得尤为宝贵。对于老师和家长来说&#xff0c;及时、准确地获取学生的成绩信息是关乎学生学习进度和效果的重要环节。那么&#xff0c;有没有一种方法能在短短一分钟内完成成绩的发布和查询呢&#xff1f;答案是肯定的&#xff0…

OceanBase4.2版本 Docker 体验

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

闲聊电脑(7)常见故障排查

闲聊电脑&#xff08;7&#xff09;常见故障排查 夜深人静&#xff0c;万籁俱寂&#xff0c;老郭趴在电脑桌上打盹&#xff0c;桌子上的小黄鸭和桌子旁的冰箱又开始窃窃私语…… 小黄鸭&#xff1a;冰箱大哥&#xff0c;平时遇到电脑故障该咋处理呢&#xff1f; 冰箱&#xf…

linux 查看打开使用了哪些端口

你可以使用 netstat 命令来查看Linux系统中正在使用的端口。例如&#xff0c;要查看所有正在使用的TCP和UDP端口&#xff0c;你可以运行&#xff1a; sudo netstat -tulpn如果你只想查看所有正在使用的TCP端口&#xff0c;你可以运行&#xff1a; sudo netstat -tpln 如果你只…

C#,红黑树(Red-Black Tree)的构造,插入、删除及修复、查找的算法与源代码

1 红黑树(Red-Black Tree) 如果二叉搜索树满足以下红黑属性,则它是红黑树: 每个节点不是红色就是黑色。根是黑色的。每片叶子(无)都是黑色的。如果一个节点是红色的,那么它的两个子节点都是黑色的。对于每个节点,从节点到后代叶的所有路径都包含相同数量的黑色节点。红…

使用yarn创建vite+vue3electron多端运行

文章目录 第一步 使用yarn创建vitevue3项目遇到创建报错看 第二步 引入electron第三步 创建main.js在electron下面的main.js写入下面代码 第四步 安装同时运行多条命令npm包&&修改package.json文件npm包增加一条electron运行脚本命令 效果图 第一步 使用yarn创建vitevu…

关于- bounding box reparameterization

因为detr以及大部分detr的变体都是将box的x,y,w,h映射到[0~1]之间&#xff1b; 这样对于小目标的检测的话就会比较困难&#xff0c;因为损失被大目标主导了&#xff0c; 所以将box的坐标编码为跟长宽占比的数值&#xff0c;具体如图图中描述所示&#xff1a;

SA3D:基于 NeRF 的三维场景分割方法

Paper: Cen J, Zhou Z, Fang J, et al. Segment anything in 3d with nerfs[J]. Advances in Neural Information Processing Systems, 2024, 36. Introduction: https://jumpat.github.io/SA3D/ Code: https://github.com/Jumpat/SegmentAnythingin3D SA3D 是一种用于 NeRF 表…

JAVA实战开源项目:生活废品回收系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

Linux中文件的权限

我们首先需要明白&#xff0c;权限 用户角色 文件的权限属性 一、拥有者、所属组和other&#xff08;用户角色&#xff09; 以文件file1为例 第一个箭头所指处即是文件的拥有者&#xff0c;拥有者为zz 第二个箭头所指处即使文件的所属组&#xff0c;所属组为zz 除去拥有者…

Docker 搭建 PaddleOCR

转自PaddleOCR docker模式 - 简书 目的: 公司要放弃第三方的ocr工具(日语),需要自己搭建训练一套,这篇是搭建 图片要标出文字的选取框 因为是日文所以ocr有专门的工具,只需要文字坐标就好如图 日文的账票需要加密一下 我得环境是 Ubuntu 22.04.1 LTS 1,下载代码 cd /hom…

10、Redis分布式系统之数据分区算法

Redis分布式系统之数据分区算法 1、什么是Redis分布式系统 ​ Redis分布式系统&#xff0c;官方称为Redis Cluster, Redis集群&#xff08;这个集群和前面的主从复制集群不同&#xff0c;这个集群可以理解为是多个主从复制集群所组成的集群&#xff09;&#xff0c;其实是Red…

js手写实现迭代器生成器函数包括【ES5】和【ES6】

/*** JS原生的集合类型数据结构&#xff0c;只有Array&#xff08;数组&#xff09;和Object&#xff08;对象&#xff09;&#xff1b;而ES6中&#xff0c;又新增了Map和Set。* 四种数据结构各自有着自己特别的内部实现&#xff0c;但我们仍期待以同样的一套规则去遍历它们&am…

垃圾清理软件大全免费 磁盘空间不足?注册表不敢乱动怎么办?ccleaner官方下载

在日常的工作中&#xff0c;面对重要文件时往往都会备份一份&#xff1b;在下载文件时&#xff0c;有时也会不小心把一份文件下载好多次。这些情况会导致电脑中出现重复的文件&#xff0c;删除这些重复文件&#xff0c;可以节省电脑空间&#xff0c;帮助提高电脑运行速度。那么…

【C语言】人生重开模拟器

前言&#xff1a; 人生重开模拟器是前段时间非常火的一个小游戏&#xff0c;接下来我们将一起学习使用c语言写一个简易版的人生重开模拟器。 网页版游戏&#xff1a; 人生重开模拟器 (ytecn.com) 1.实现一个简化版的人生重开模拟器 &#xff08;1&#xff09; 游戏开始的时…

openAI key 与ChatGPTPlus的关系,如何升级ChatGPTPLus

一、前言 先详细介绍一下Plus会员和Open API之间的区别&#xff1a; 实际上&#xff0c;这两者是相互独立的。举例来说&#xff0c;虽然您开通了Plus会员&#xff0c;并不意味着您就可以使用4.0版本的API。尽管这两个账户可以是同一个&#xff0c;但它们是完全独立的平台。 …

C++的一些基础语法

前言&#xff1a; 本篇将结束c的一些基础的语法&#xff0c;方便在以后的博客中出现&#xff0c;后续的一些语法将在涉及到其它的内容需要用到的时候具体展开介绍&#xff1b;其次&#xff0c;我们需要知道c是建立在c的基础上的&#xff0c;所以c的大部分语法都能用在c上。 目…