【C语言】:字符函数和字符串函数

这里写目录标题

  • 1、strlen的使用和模拟实现
  • 2、strcpy的使用和模拟
  • 3、strcat 的使用和模拟实现
  • 4、strcmp 的使用和模拟实现
  • 5、strncpy 函数的使用
  • 6、strncat 函数的使用
  • 7、strncmp函数的使用
  • 8、strstr 的使用和模拟实现
  • 9、strtok 函数的使用
  • 10、strerror 函数的使用
  • 11、字符分类函数
    • 11.1 字符转换

1、strlen的使用和模拟实现

size_t strlen ( const char * str );

  • 返回字符串 str 的长度

    • 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包含 ‘\0’ )
    • 参数指向的字符串必须要以 ‘\0’ 结束。
    • 注意函数的返回值为size_t,是⽆符号的( 易错 )。
    • strlen的使⽤需要包含头⽂件string.h 。

这个我们举个例子实践一下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{char* str1 = "abc";char* str2 = "abcdef";if (strlen(str1) - strlen(str2) > 0)printf("大于\n");elseprintf("小于等于\n");return 0;
}//大于

为什么上面这个代码的结果是大于呢?我们可以看到strlen(str1)计算出的结果是3,而strlen(str2)计算出的结果是6,3-6= -3

因为-3在内存中是以补码的形式存储的,因此我们可以得到-3在内存中的存储如下:
在这里插入图片描述
又因为我们在使用strlen函数时,他的返回值是无符号的,所以两个整数相减也是无符号数;而对于无符号数,他的原码=反码=补码;因此11111111 111111111 11111111 11111111 11111101就是最后的返回结果,这个值显然是大于0的。

strlen的模拟实现:

方法一:

//计数器⽅式
#include<stdio.h>
#include<string.h>
#include<assert.h>
size_t my_strlen(const char* str)
{int count = 0;assert(str!=NULL);while (*str != '\0'){count++;str++;}return count;
}
int main()
{char str[] = "abcdef";size_t ret=my_strlen(str);printf("%u\n", ret);return 0;
}

方法二:

//不能创建临时变量计数器
#include<stdio.h>
#include<string.h>
size_t my_strlen(const char* str)
{assert(str!=NULL);if (*str == '\0')return 0;elsereturn (1 + my_strlen(str + 1));
}
int main()
{char str[] = "abcdef";size_t ret = my_strlen(str);printf("%u\n", ret);return 0;
}

方法三:

//指针-指针的⽅式
#include<stdio.h>
#include<string.h>
size_t my_strlen(const char* str)
{assert(str!=NULL);char* p = str;while (*p)p++;return p - str;
}
int main()
{char str[] = "abcdef";size_t ret = my_strlen(str);printf("%u\n", ret);return 0;
}

2、strcpy的使用和模拟

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

  • 将源指向的字符串复制到目标指向的数组中,包括终止 null 字符(并在该点停止)。

• 源字符串必须以 ‘\0’ 结束。
• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。
• ⽬标空间必须⾜够⼤,以确保能存放源字符串。
• ⽬标空间必须可修改。

举个例子:

//拷贝一个字符串
int main()
{char str1[] = { 0 };char str2[] = "hello world";strcpy(str1, str2);printf("%s\n", str1);return 0;
}//hello world

strcpy的模拟实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* sur)
{char* ret = dest;assert(dest != NULL);assert(sur != NULL);while (*sur!='\0'){*dest = *sur;sur++;dest++;}*dest = *sur;return ret;
}
int main()
{char str1[40] = "************";char str2[20] = "hello world";my_strcpy(str1, str2);printf("%s\n",str1);return 0;
}

3、strcat 的使用和模拟实现

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

  • 将源字符串的副本追加到目标字符串。

• 源字符串必须以 ‘\0’ 结束。
• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。

举个例子使用一下:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "hello ";char arr2[20] = "world";strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}//hello world

strcat的模拟实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* dest, char* src)
{char* ret = dest;assert(dest != NULL);assert(src != NULL);while (*src){if (*dest == '\0'){*dest = *src;dest++;src++;}elsedest++;}return ret;
}
int main()
{char arr1[20] = "hello ";char arr2[20] = "world";my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

4、strcmp 的使用和模拟实现

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

  • 将 字符串 str1 与 C 字符串 str2 进行比较。

  • 开始比较每个字符串的第一个字符。如果它们彼此相等,则继续执行下一对,直到字符不同或达到终止字符。

    • 标准规定:

返回值表明
>0第⼀个字符串⼤于第⼆个字符串
=0第⼀个字符串等于第⼆个字符串
<0第⼀个字符串⼩于第⼆个字符串

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

举个例子证明一下:

#include<stdio.h>
#include<string.h>
int main()
{int ret1 = strcmp("abcdef", "abq");printf("%d\n", ret1);//-1int ret2 = strcmp("bbcdef", "abq");printf("%d\n", ret2);//1int ret3 = strcmp("abc", "abc");printf("%d\n", ret3);//0return 0;
}

strcmp 的模拟实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{assert(str1 != NULL);assert(str2 != NULL);while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;
}
int main()
{char arr1[] = "ab";char arr2[] = "abq";int ret = my_strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}

5、strncpy 函数的使用

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

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

    • 将源的前 num 个字符复制到目标。如果在复制 num 个字符之前找到源字符串的末尾(由 null 字符表示),则 destination 将用零填充,直到将 num 个字符写入该字符串。

    • 如果 source 的长度大于 num,则不会在目标末尾隐式附加 null 字符。因此,在这种情况下,destination 不应被视为以 null 结尾的字符串(这样读取它会溢出)。

    •目的地和源不得重叠。

我们写个程序来验证一下这个过程:

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

当我们开始调试时,打开窗口监视,我们可以发现arr2拷贝了三个字符在arr1中,使得arr1中的前三个字符变成了“ *** ”。
在这里插入图片描述

6、strncat 函数的使用

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

  • 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加一个’ \0 '字符。

    • 如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾。

我们写个函数来验证一下:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "abcdef\0yyyyyyyyy";char arr2[] = "*******";strncat(arr1, arr2, 4);return 0;
}

依旧是调试起来验证,我们可以发现strncat是\0之前追加的。
在这里插入图片描述

7、strncmp函数的使用

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

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

    • 标准规定:

返回值表明
>0第⼀个字符在str1中的值大于str2中的值
=0两个字符串的内容相等
<0第⼀个字符在str1中的值小于str2中的值

举个例子:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcquer";char arr2[] = "abcdef";printf("%d\n", strncmp(arr1, arr2, 4));//1return 0;
}

8、strstr 的使用和模拟实现

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

  • 字符串中找子字符串

• 函数返回字符串str2在字符串str1中第⼀次出现的位置。
• 字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。

写个程序验证一下:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcdefabcdef";char arr2[] = "def";char* ret = strstr(arr1, arr2);printf("%s\n", ret);//defabcdefreturn 0;
}

strstr 的模拟实现:

#include<stdio.h>
#include<string.h>
char* my_strstr(char* str1, char* str2)
{char* cp = str1;char* s1 = cp;char* s2 = str2;while (*cp){s1 = cp;s2 = str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}
int main()
{char arr1[] = "abcdefabcdef";char arr2[] = "def";char* ret = my_strstr(arr1, arr2);printf("%s\n", ret);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 指针。

这里写个程序来理解一下:

#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "zhangwei@yeah.net";char copy[30];strcpy(copy, arr);char sep[] = "@.";char* ret = NULL;for (ret = strtok(copy, sep); ret!=NULL; ret = strtok(NULL, sep)){printf("%s\n", ret);}return 0;
}

在这里插入图片描述

10、strerror 函数的使用

char * strerror ( int errnum );

  • strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。

在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明
的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动
的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应
的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是
有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。

#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印⼀下0~10这些错误码对应的信息
int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}

在Windows11+VS2022环境下输出的结果如下:

在这里插入图片描述

11、字符分类函数

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

11.1 字符转换

上面这些函数的使⽤⽅法⾮常类似,我们来理解⼀个函数,其他的可以照猫画虎:

#include<stdio.h>
#include<ctype.h>
int main()
{printf("%d\n", isupper('A'));//1printf("%d\n", isdigit('X'));//0printf("%c\n", tolower('A'));//aprintf("%c\n", tolower ('b'));//breturn 0;
}
#include<stdio.h>
#include<ctype.h>
int main()
{char arr[20] = { 0 };gets(arr);//读一个串,遇到空格继续char* p = arr;while (*p){if (isupper(*p)){*p = tolower(*p);}p++;}printf("%s\n", arr);return 0;
}

假如我们输入:I am A Good Boy
则程序输出为:
在这里插入图片描述

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

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

相关文章

C语言——关于指针运算的例题分析

1.指针运算中关于 sizeof 和 strlen 的例题分析 1. sizeof(数组名)&#xff0c;这⾥的数组名表⽰整个数组&#xff0c;计算的是整个数组的⼤⼩。 2. &数组名&#xff0c;这⾥的数组名表⽰整个数组&#xff0c;取出的是整个数组的地址。 3. 除此之外所有的数组名都表⽰…

汇编入门--基础知识(1)

1.汇编语言的概念 汇编语言是一种低级编程语言&#xff0c;它与计算机的机器语言非常接近&#xff0c;但比机器语言更易于人类阅读和理解。汇编语言是用一系列的助记符来表示机器语言的操作码和操作数。每种计算机体系结构&#xff08;如x86、ARM等&#xff09;都有自己的汇编语…

12.java openCV4.x 入门-HighGui之图像窗口显示

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

算法刷题Day29 |491.递增子序列、46.全排列、47.全排列 II

目录 0 引言1 递增子序列1.1 我的解题 2 全排列2.1 我的解题 3 全排列 II3.1 我的解题 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;算法刷题Day29 |491.递增子序列、46.全排列、47.全排列 II❣️ 寄语&…

linux安装dubboAdmin

1.环境准备&#xff1a; jdk-8u391-linux-x64apache-maven-3.9.6apache-tomcat-8.5.100 2.安装注册中心zookeeper zookeeper的安装看我的另一篇文章&#xff0c;安装完成后保持启动状态 linux安装Zookeeper的详细步骤-CSDN博客 3.安装dubboadmin 源码下载地址&#xff1a;R…

vue快速入门(十四)reduce求和

注释很详细&#xff0c;直接上代码 新增内容 非嵌套情况求和嵌套情况求和 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale…

C++第十五弹---string基本介绍(一)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、什么是STL 2、STL的版本 3、STL的六大组件 4、STL的重要性 5、如何学习STL 6、STL的缺陷 7、为什么学习string类 7.1、C语言中的字符串…

Google play开发者新手必看:2024最新最全的谷歌上架避坑指南

Google Play作为一个全球性的Android应用分发平台&#xff0c;吸引了无数开发者的目光。据统计&#xff0c;该平台的月活跃用户数已超过20亿&#xff0c;这无疑是一个巨大的市场。 但随着行业的发展&#xff0c;谷歌风控和审核机制不断升级&#xff0c;即便是经验丰富的开发者也…

Nginx配置文件修改结合内网穿透实现公网访问多个本地web站点

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

抖音评论ID提取工具|视频关键词评论批量采集软件

抖音评论ID提取工具&#xff1a;批量抓取抖音评论 抖音评论ID提取工具是一款功能强大的软件&#xff0c;可以帮助您批量抓取抖音视频下的评论信息。通过输入关键词和评论监控词&#xff0c;即可进行评论的抓取&#xff0c;并提供评论昵称、评论日期、评论内容、命中关键词以及所…

【CSDN活动】人工智能:前沿科技中的创业机遇与挑战

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 人工智能&#xff1a;前沿科技中的创业机遇与挑战一、AI技术的快速发展与应用拓…

QML学习记录:并排页面切换效果的实现

定义一个ApplicationWindow窗口&#xff0c;通过添加SwipeView和PageIndicator来实现页面切换效果和显示当前页面位置的指示器。 ApplicationWindow {id:rootvisible: truewidth: 340height: 480title: qsTr("SwipeView") // 定义一个SwipeView用于页面切换效果 Swip…

Oracle ADG主备切换

文章目录 一、主库切换备库二、备库切换主库三、新备库&#xff08;原主库&#xff09;启用实时日志应用四、新主库切换日志五、查看当前主备库状态 一、主库切换备库 # 查看切换前的状态&#xff0c;确认当前从操作的是主库 select name,open_mode,switchover_status from v$…

无人机倾斜摄影技术在智慧城市中的应用

随着智慧城市的不断发展和完善&#xff0c;新兴热门技术也不断崛起。无人机技术作为其中之一&#xff0c;具有操作简单、应用灵活等优势&#xff0c;受到了各个行业的青睐。现阶段&#xff0c;无人机技术与5G移动通信系统、人工智能系统深度融合&#xff0c;实现了无人机技术的…

LLMs之FreeGPT35:FreeGPT35的简介、安装和使用方法、案例应用之详细攻略

LLMs之FreeGPT35&#xff1a;FreeGPT35的简介、安装和使用方法、案例应用之详细攻略 目录 FreeGPT35的简介 FreeGPT35的安装和使用方法 1、部署和启动服务 Node 2、使用 Docker 部署服务&#xff1a; 运行 Docker 容器以部署服务 使用 Docker Compose 进行更方便的容器化…

抖音视频无水印采集软件|视频关键词批量提取工具

轻松实现抖音视频批量下载&#xff0c;让营销更高效&#xff01; 随着抖音视频在营销领域的日益普及&#xff0c;如何高效地获取并管理大量视频资源成为了市场人员的重要挑战。针对这一需求&#xff0c;我们推出了一款强大的音视频无水印采集软件&#xff0c;帮助您轻松实现批量…

C++笔记:学习使用C++

一.命名空间 namespace 名字 作用&#xff1a;一种用来隔离命名冲突的机制&#xff0c;是C的一项特性 例如&#xff1a; #include<iostream>namespace A {void func_1() {printf("hello world A\n");return ;} }namespace B {void func_1() {printf("hell…

MySQL——查询数据的处理

一、并列 连接两个数据列的值&#xff0c;并进行输出的格式化处理&#xff08;显示为一种统一的格式&#xff09; concat( 列 1 格式化字 符 ) mysql> select concat(vend_name, vend_country) from vendors; --------------------------------- | concat(vend_name, ve…

某211大学src挖掘

信息收集 这次信息收集比较玄学&#xff0c;起初就是用谷歌语法搜了一下带注册功能的点 然后就找到了本次目标站的注册点: 这边的学号啥的我都是不知道的而且这边最后显示的不是注册&#xff0c;显示的是提交所以可以断定注册账号得需要管理员审核信息才能注册&#xff0c;所以…

【Unity渲染】渲染管线原理

整理自B站UPKerry佬的视频【【教程】技术美术入门&#xff1a;渲染管线概述】 https://www.bilibili.com/video/BV1Q54y1G7v3/?share_sourcecopy_web&vd_source7e6249c05fba6efe32e8867373f75917 应用阶段 、几何阶段顶点处理、光栅化、片元处理、输出合并 应用阶段是CUP…