字符串函数(C语言详解)

1.字符串简介

字符串是一串连续的且以\0结尾的字符

char arr[]="zhangsan";//将字符串存到数组里面
char*a="lisi";//常量字符串
char arr1[]={'z','h','a','n','g'};//字符数组

注意:

1.以第一种形式初始化字符串时,计算机会自动在字符串末尾加上\0,所以在给数组申请内存空间时,需要多申请一个字节的内存来存放\0

2.第二种形式是常量字符串,是不可以被修改

3.第三种形式是字符数组,末尾没有\0,输出时需要一个字符一个字符的输出,如果想要像字符串一样一次输出,可以在最后一个字符末尾手动加上一个\0(在确保内存空间足够的情况下),然后用%s打印

4.一个字符占用一个字节的内存空间

5.字符串也可以是中文,一个中文汉字占两个字节(GBK编码)

2.字符串函数

2.1字符串函数的头文件

#include<string.h>

2.2 strlen()函数

2.2.1strlen函数的原型(计算字符串长度)

size_t strlen ( const char * str );

strlen函数的形参是一个char类型的地址,因为我们需要防止字符串的内容被修改,所以加上

const防止内容被修饰,返回值是size_t类型,也就是无符号整形,因为字符串的个数不可能为负数

2.2.2举例说明

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

因为strlen的返回值是size_t,所以我们用size_t len来接收返回值,当然也可以用int来接收,结果也是正确的

2.2.3模拟实现strlen()函数

模拟1(计数)

size_t my_strlen(const char* str)
{assert(str);//断言str是否为空指针size_t count = 0;while (*str)//因为\0的的ASCLL码为0,所以当str指向\0时,不进行循环{count++;//如果str不指向\0,那么count++,统计字符个数str++;//统计完一个字符,向后走一个字节}return count;
}

模拟2(递归)

size_t my_strlen1(const char* str)
{assert(str);if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}

模拟3(指针减指针)

size_t my_strlen(const char* str)
{assert(str);char* p = str;while (*str){str++;}return str - p;
}

2.3 strcpy()函数

2.3.1strcpy函数的原型(字符串拷贝)

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

char*destination用来接收拷贝的目标地址,const char *source用来接收源字符串地址

2.3.2 举例说明

strcpy函数在使用时,会将目标空间内容覆盖

注意:1.源字符串必须以\0结尾

           2.strcpy会将\0拷贝到目标空间

           3.确保目标空间足够大,能放下源字符串

           4.确保目标空间可修改

2.3.3模拟实现strcpy()函数

char* my_strcpy(char* dest, const char* src)
{char* ret = dest;//记录一下起始位置的地址assert(dest != NULL);assert(src != NULL);while (*dest++=*src++)//挨个赋值,如果遇到\0,将\0赋值后,条件语句为假,就退出循环{;}return ret;
}

2.4 strcat()函数

2.4.1 strcat函数的原型(字符串连接)

char * strcat ( char * destination, const char * source );

2.4.2 举例说明

int main()
{char arr[100] = "1234567890";char brr[] = "888888";strcat(arr,brr);printf("%s", arr);;return 0;
}

注意:1.源字符串必须以\0结尾

           2.目标字符串必须要与\0,否则没办法知道从哪里开始追加

           3.确保目标空间足够大,能放下目标字符串和源字符串

           4.确保目标空间可修改

2.4.3模拟实现strcat()函数

char* my_strcat(char* dest, const char* src)
{char* ret = dest;assert(dest != NULL);assert(src != NULL);while (*dest){dest++;//循环找到\0的位置}while (*dest++ = *src++)//从\0的位置开始追加{;}return ret;
}

2.5 strcmp()函数

2.5.1strcmp函数的原型(字符串比较)

int strcmp ( const char * str1, const char * str2 );

strcmp函数是一个一个字符比较,如果str1所指向的字符大于str2所指向的字符,返回大于0的数,如果str1所指向的字符小于str2所指向的字符,返回小于0的数,如果相等,继续比较下一对字符,直到比到\0为止,如果比到\0依然相等,那么返回0(字符串长度相等的情况)

2.5.2举例说明

strcmp("abcd","abcd");//返回值为0
两段字符串相同返回0strcmp("abc","abcd");//返回值为负数
第一个字符串的第四个字符为\0,与第二个字符串的d比较是小于的,返回一个负数strcmp("abcd","abc");//返回值为正数
d与\0比较是大于的,返回一个正数strcmp("abs","abcd");//返回值为正数
第一个字符串的第三个字符s与第二个字符串的c比较是大于的,返回一个正数,后面的都不用比较了strcmp("abcd","abs");//返回值为负数
第一个字符串的第三个字符c与第二个字符串的s比较是小于的,返回一个负数,后面的都不用比较了

2.5.3模拟实现strcmp()函数

int my_strcmp(const char* str1, const char* str2)
{assert(str1 != NULL);assert(str2 != NULL);while (*str1 == *str2)//如果两个字符相等,那么进入循环{if (*str1 == '\0')//如果两个字符相等并且其中一个字符为\0,那么这两个字符串都走到了结尾,所以这两个字符串相等,直接返回0return 0;str1++;str2++;//不等于\0就使指针指向下一个位置,然后继续比较}return *str1 - *str2;//如果两个字符不相等,那么用str1指向的字符减去str2指向的字符,也就是两个字符的ASCLL码相减的到一个整数
}

2.6 strstr()函数

2.6.1strstr函数的原型(字符串查找)

const char * strstr ( const char * str1, const char * str2 );

函数返回字符串str2在字符串str1中第⼀次出现的位置

2.6.2举例说明

int main()
{char arr[100] = "1234567890";char brr[] = "456";printf("%s",strstr(arr,brr) );return 0;
}

上面这段代码的输出结果为4567890

2.6.3模拟strstr()函数

char* my_strstr(const char* str1, const char* str2)
{if (!*str2)//如果str2没有字符,那么结尾为\0,\0的ASCLL码值为0,非0为真,就直接返回str1的起始地址return (char*)str1;char* cp = (char*)str1;char* s2;char* s1;while (*cp){s1 = cp;//因为我们要比较一段字符,当我们找到第一个字符时,需要往后比较剩余的字符是否相同s2 = (char*)str2;while (*s1 && *s2 && !(*s1 - *s2))//如果s1和s2所指向的字符都不为\0,并且两个字符相同,那么两个字符向后走,比较其他的字符s1++, s2++;if (!*s2)//如果s2走到了\0,那么说明字符串找到了,我们就返回第一个相同字符的地址return cp;cp++;//如果没找到,就继续cp++,用后面的字符和str2的第一个字符比较}return NULL;//如果没有找到,就返回空指针
}

这个是目前最复杂的模拟实验

2.7strtok()函数

2.7.1strtok函数的原型(切分字符串)

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

使用注意:

1.sep参数指向一个字符串,定义了用作分隔符的字符集合

2.第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标

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

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

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

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

2.7.2举例说明

int main()
{char str1[] = "123.21.12@21.12";char str2[] = "@.";//定义被切割的节点char str3[100];char *str4 = NULL;strcpy(str3, str1);for (str4 = strtok(str3, str2); str4 != NULL; str4 = strtok(NULL, str2)){printf("%s\n", str4);}return 0;
}

2.8strncpy()函数

2.8.1strncpy函数的原型(拷贝n个字符)

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

num表示需要拷贝的字符数

2.8.2举例说明

int main()
{char arr[] = "1231231";char brr[] = "8888";strncpy(arr, brr, 4);printf("%s", arr);return 0;
}

输出结果为88881231

2.8.3模拟实现strncpy()函数

char*my_strncpy(char* dest, const char* src, size_t num)
{char* ret = dest;while (num){*dest++ = *src++;num--;}return ret;
}

2.9strncat()函数

2.9.1strncat函数的原型

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

strncat函数的形参num表示要拼接的字符个数,最后补一个\0,同样要保证目标空间足够大

2.9.2举例说明

int main()
{char arr[20] = "1231231";char brr[] = "8888";strncat(arr, brr, 4);printf("%s", arr);return 0;
}

输出结果为12312318888

2.9.3模拟实现strncat()函数

char* my_strncat(char* dest,const char* src, size_t x)
{assert(dest && src); char* ret = dest;while (*dest){dest++;}while (x){*dest++ = *src++;x--;}return ret;
}

2.10strncmp()函数

2.10.1strncmp函数的原型

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

 num表示要比较的字符个数

2.10.2举例说明

int main()
{char arr[20] = "1231231";char brr[] = "1237";printf("%d", strncat(arr, brr, 2));return 0;
}

 2.10.3模拟实现strncmp()函数

int my_strcmp(char* arr1, char* arr2,size_t x)
{while (*arr1 == *arr2){if (*arr1 == '\0'){return 0;}x--;if (x == 0){break;}arr1++;arr2++;}return *arr1 - *arr2;
}

3.字符分类函数

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任何可打印字符,包括图形字符和空白字符

以上这些函数形参和返回值都类似,我们以islower为例:

int islower ( int c );

islower 是能够判断参数部分的 c 是否是小写字⺟的。
通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0

4.字符转换函数

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

头文件也为ctype.h

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

使用用例

#include <stdio.h>
#include <ctype.h>
int main ()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c))
c = toupper(c);
putchar(c);
i++;
}
return 0;
}

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

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

相关文章

GraspNet-baseline复现----Linux-Ubuntu

1.基本环境 Ubuntu 20.04Cuda 11.0 、cuDNN 80.0Python 3.7.16PyTorch 1.7.0 2.环境配置 PyTorch的版本对Cuda和Python的版本都有依赖&#xff0c;所以基本步骤是 确定需要安装的PyTorch版本 —> 通过 网站 确定对应的cuda版本和python版本 —> 创建虚拟环境配置环境。…

Node.js基础+原型链污染

Node.js基础 概述&#xff1a;简单来说Node.js就是运行在服务端的JavaScript&#xff0c;Node.js是一个基于Chrome JavaScript运行时建立的一个平台 大小写变换&#xff1a; toUpperCase&#xff08;&#xff09;&#xff1a;将小写字母转为大写字母&#xff0c;如果是其他字…

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

使用FFmpeg源码配置程序configure查看所有支持的编码器/解码器/封装/解封装及网络协议

查看支持编码器: configure --list-encoders 查看支持编码器: configure --list-decoders 查看所有支持的封装: configure --list-muxers 查看所有支持的解封装: configure --list-demuxers 查看所有支持的网络通信协议: configure --list-protocols

解决jsp request.getParameter乱码问题(兼容Tomcat 6~8三个版本)

JSP页面写法&#xff1a; <% page contentType"text/html; charsetutf-8" language"java" %> <% page import"java.io.*" %> <%! int getServerVersion(HttpServletRequest request) {ServletContext application request.getS…

移远通信亮相AWE 2024,以科技力量推动智能家居产业加速发展

科技的飞速发展&#xff0c;为我们的生活带来了诸多便利&#xff0c;从传统的家电产品到智能化的家居设备&#xff0c;我们的居家生活正朝着更智能、更便捷的方向变革。 3月14日&#xff0c;中国家电及消费电子博览会&#xff08;Appliance&electronics World Expo&#xf…

【物联网】Modbus 协议及Qinghub物联网平台应用

Modbus 协议简介 QingHub设计器在设计物联网数据采集时不可避免的需要针对Modbus协议的设备做相关数据采集&#xff0c;这里就我们的实际项目经验分享Modbus协议 你可以通过QingHub作业直接体验试用&#xff0c;也可以根据手册开发相应的代码块。 qinghub项目已经全面开源。 …

sqllab第十九关通关笔记

知识点&#xff1a; 错误注入 最大长度为32位&#xff1b;如果目标长度>32时&#xff0c;需要利用截取函数进行分段读取referer注入 insert语句update语句 通过admin admin进行登录发现页面打印除了referer字段的信息 这应该是一个referer注入 首先进行测试一下 构造payl…

基于SpringBoot和Echarts的全国地震可视化分析实战

目录 前言 一、后台数据服务设计 1、数据库查询 2、模型层对象设计 3、业务层和控制层设计 二、Echarts前端配置 1、地图的展示 2、次数排名统计 三、最终结果展示 1、地图展示 2、图表展示 总结 前言 在之前的博客中基于SpringBoot和PotsGIS的各省地震震发可视化分…

C++提高笔记(四)---STL容器(stack、queue、list)

1、stack容器&#xff08;栈&#xff09; 1.1 栈stack基本概念 概念&#xff1a;stack是一种先进后出&#xff08;First In Last Out&#xff0c;FILO&#xff09;的数据结构&#xff0c;它只有一个出口 栈中只有顶端的元素才可以被外界调用&#xff0c;因此栈不允许有遍历行…

使用C#的winform控制数据库实例服务的运行状态

一、得到sqlserver的实例名 二、引用对应的程序集和命名空间 using System.ServiceProcess; C#操作服务要用的类 ServiceController 声明类 private ServiceController serviceController new ServiceController("MSSQLSERVER"); 三、判断服务状态 serviceCon…

上证指数000001行情数据API接口

# 测试&#xff1a;返回不超过10条数据&#xff08;2年历史&#xff09; https://tsanghi.com/api/fin/index/CHN/daily?tokendemo&ticker000001&order2Python示例 import requestsurl f"https://tsanghi.com/api/fin/index/CHN/daily?tokendemo&ticker000…

要将镜像推送到GitLab的Registry中的步骤

1、通过cli 模式登录gitlab &#xff08;命令行模式&#xff09; docker login git.asc-dede.de Username: haiyang Password: Login Succeeded 2、查看我的本地镜像&#xff1a; 3&#xff0c;推送镜像apollo_core到对应的gitlab项目的Registry 中 docker push registry.gi…

「Linux系列」Linux简介及常见的Linux系统

文章目录 一、Linux简介二、常见的Linux系统三、Linux 应用领域四、Linux对比Windows五、相关链接 一、Linux简介 Linux是一种自由和开放源代码的类Unix操作系统&#xff0c;它最初是作为Unix操作系统的替代品而开发的。Linux操作系统的内核由林纳斯托瓦兹在1991年首次发布&am…

Sunday 算法介绍

1. Sunday 算法介绍 「Sunday 算法」 是一种在字符串中查找子串的算法&#xff0c;是 Daniel M.Sunday 于1990年提出的字符串模式匹配算法。 Sunday 算法思想&#xff1a;对于给定文本串 T 与模式串 p&#xff0c;先对模式串 p 进行预处理。然后在匹配的过程中&#xff0c;当发…

UE5.1 iClone8 正确导入角色骨骼与动作

使用iClone8插件Auto Setup 附录下载链接 里面有两个文件夹,使用Auto Setup C:\Program Files\Reallusion\Shared Plugins 在UE内新建Plugins,把插件复制进去 在工具栏出现这三个人物的图标就安装成功了 iClone选择角色,导入动作 选择导出FBX UE内直接导入 会出现是否启动插件…

docker的常用指令

docker的常用指令 从docker镜像仓库&#xff0c;搜索所有和mysql有关的镜像 docker search mysql 从docker仓库拉取mysql docker pull mysql这里的mysql是指使用search搜索出来的所有容器的NAME 如果和我一样遇到以下问题&#xff1a; 我可以登录阿里云的官网&#xff0c;找…

基于springboot+vue实现计算机等级考试报名系统项目【项目源码+论文说明】计算机毕业设计

基于springbootvue实现计算机等级考试报名演示 摘要 在进入二十一世纪之后&#xff0c;网络发展越来越迅速&#xff0c;人们的很多生活习惯与消费习惯都随之发生了改变&#xff0c;计算机技术为人们的生活带来了很多的便利。而计算机技术是我国各个教育阶段中的一门必修课程&a…

Golang中map数据结构字段解析

Golang里map底层数据结构具体如下图所示&#xff1a; map其实就是一个指向 hmap 的指针&#xff0c;占用了8个字节 hmap各自段存放的字段意义如下&#xff1a; 字段含义countmap中元素的个数&#xff0c;对应len (map)的值flags状态标志位&#xff0c;标记map的一些状态B桶数…

Spring中使用内置的tomcat容器启动后自动退出问题解决方法

在Spring中使用内置的tomcat 启动后自动退出 退出代码为0 且不报任务错误的解决方法. 日志如下: Connected to the target VM, address: 127.0.0.1:51129, transport: socket 三月 15, 2024 11:55:00 下午 org.apache.coyote.AbstractProtocol init 信息: Initializing Proto…