C语言 字符函数汇总,模拟实现各字符函数(炒鸡详细)

目录

求字符串长度

strlen

示例

模拟实现strlen

长度不受限制的字符串函数

strcpy

示例

模拟实现strcpy

strcat

模拟实现strcat

strcmp

示例 

模拟实现strcmp

长度受限制的字符串函数介绍

strncpy

示例

模拟实现strncpy

strncat

示例 

模拟实现strncat 

strncmp

示例

模拟实现strncmp

字符串查找

strstr

示例

模拟实现strstr

strtok

示例

模拟实现strtok

错误信息报告

strerror

示例 

字符分类函数


求字符串长度

strlen

size_t strlen ( const char * str );
  1. 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 '\0' )
  2. 参数指向的字符串必须要以 '\0' 结束。
  3. 注意函数的返回值为size_t,是无符号的

示例

 const char*str1 = "abcdef";const char*str2 = "bbb";if(strlen(str2)-strlen(str1)>0){printf("str2>str1\n");} else{printf("srt1>str2\n");}

模拟实现strlen

#include <stdio.h>size_t my_strlen(const char* str) {size_t count = 0;while (str[count] != '\0') {count++;}return count;
}int main() {const char* str = "Hello, World!";size_t length = my_strlen(str);printf("字符串的长度为: %zu\n", length);return 0;
}

长度不受限制的字符串函数

strcpy

copy字符串到目标字符串,应该使用strcpy

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

  1. 源字符串必须以 '\0' 结束。
  2. 会将源字符串中的 '\0' 拷贝到目标空间。
  3. 目标空间必须足够大,以确保能存放源字符串。
  4. 目标空间必须可变

示例

    char name[20] = {0};strcpy(name, "zhang\0hai");printf("%s\n", name); // zhang

模拟实现strcpy

char *my_strcpy(char *dest, const char *str)
{assert(dest && str);char *res = dest;while (*dest++ = *str++){}return res;
}   char arr1[] = "abc\0def";
char arr2[] = {0};
my_strcpy(arr2, arr1);
printf("%s\n", arr2); // abc

strcat

拼接字符串到目标字符串,应该使用strcat

char * strcat ( char * destination , const char * source );
  1. 源字符串必须以 '\0' 结束。
  2. 目标空间必须有足够的大,能容纳下源字符串的内容。
  3. 目标空间必须可修改。
    /* 同样 strcpy同strcpy大概一致,需保持足够大的空间,遇\0停止 */char arr1[] = "demo";// strcat(arr1, "emo");// printf("%s", arr1); // demoemostrcat(arr1, "em\0o");printf("%s", arr1); // demoem

模拟实现strcat

char *my_strcat(char *dest, const char *str)
{char *res = dest;assert(dest && str);while (*dest != '\0') // 找到目标空间的末尾\0{dest++;}while (*dest++ = *str++){;}return res;
}char arr3[20] = "hello ";
my_strcat(arr3, "world");
printf("%s\n", arr3); // hello world

strcmp

两个字符串比较相等,应该使用strcmp

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

比较是基于字符的 ASCII 值来进行的。strcmp() 会逐个比较两个字符串对应位置上的字符的 ASCII 值,并按照以下规则返回结果:

当找到不同的字符时,根据其 ASCII 值的大小关系决定比较结果。较小的字符对应的字符串被认为是较小的。如果一个字符串是另一个字符串的前缀,则较短的字符串被认为是较小的。

strcmp() 是区分大小写的。大写字母的 ASCII 值小于小写字母的 ASCII 值。

strcmp() 返回一个整数,表示两个字符串的比较结果。

  1. 如果字符串相等,则返回 0。
  2. 如果第一个字符串小于第二个字符串,则返回一个负整数。
  3. 如果第一个字符串大于第二个字符串,则返回一个正整数。

下面是一些比较的示例:

  •      strcmp(“apple”, “apple”) 返回 0,因为两个字符串相等。
  •      strcmp(“apple”, “banana”) 返回一个负整数,因为 “apple” 的 ASCII 值小于 “banana”。
  •      strcmp(“banana”, “apple”) 返回一个正整数,因为 “banana” 的 ASCII 值大于 “apple”。
  •      strcmp(“apple”, “Apples”) 返回一个正整数,因为 ‘a’ 的 ASCII 值大于 ‘A’。

示例 

    char arr1[20] = "zhangsan";char arr2[20] = "zhangsanfeng";int res = strcmp(arr1, arr2);if (res < 0){printf("<\n"); // <}else if (res == 0){printf("=\0");}else{printf(">\0");}

模拟实现strcmp

int my_strcmp(const char *s1, const char *s2)
{assert(s1 && s2);while (*s1 == *s2){if (*s1 == '\0'){return 0; // 如果全等 abc == abc}s1++;s2++;}return *s1 - *s2;
}char arr4[] = "zhanghai";
char arr5[] = "zhanghai";
printf("%d\n", my_strcmp(arr4, arr5)); // 0

长度受限制的字符串函数介绍

strncpy

strncpy 函数用于从源字符串复制指定数量的字符到目标字符串中,如果源字符串长度小于指定长度,则会用空字符进行填充。

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

  1. 拷贝num个字符从源字符串到目标空间。
  2. 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

示例

 在这个示例中,我们声明了一个目标字符串 dest,一个源字符串 src 以及要复制的字符数量 n。然后,我们使用 strncpy 函数将 src 中的前 n 个字符复制到 dest 中。最后,我们手动添加了一个结尾标记 \0,以确保目标字符串正确终止。最后,我们打印复制后的目标字符串 dest

请注意,要确保目标字符串 dest 的长度足够大,以容纳复制的字符和结尾标记。如果 n 大于等于源字符串的长度,那么目标字符串将没有结尾标记

#include <stdio.h>
#include <string.h>int main() {char dest[20];const char* src = "Hello, World!";size_t n = 5;printf("源字符串: %s\n", src);printf("复制的字符数: %zu\n", n);strncpy(dest, src, n);dest[n] = '\0';  // 添加结尾标记printf("目标字符串: %s\n", dest);return 0;
}

模拟实现strncpy

#include <stdio.h>char* my_strncpy(char* dest, const char* src, size_t n) {size_t i;for (i = 0; i < n && src[i] != '\0'; i++) {dest[i] = src[i];}for ( ; i < n; i++) {dest[i] = '\0';  // 如果源字符串长度小于 n,则用空字符填充}return dest;
}int main() {char dest[20];const char* src = "Hello, World!";size_t n = 5;printf("源字符串: %s\n", src);printf("复制的字符数: %zu\n", n);my_strncpy(dest, src, n);printf("目标字符串: %s\n", dest);return 0;
}

strncat

char * strncat ( char * dest , const char * src , size_t n );

strncat 用于将指定长度的字符串拼接(追加)到目标字符串的末尾。

参数说明:

  • dest:目标字符串,要将源字符串拼接到其末尾的字符串。
  • src:源字符串,要拼接到目标字符串末尾的字符串。
  • n:要拼接的最大字符数,即 src 中要拷贝的字符数。

strncat 函数的作用是将 src 指向的字符串的前 n 个字符(如果 src 的长度小于 n 则拷贝整个字符串)追加到 dest 指向的字符串的末尾,并在目标字符串的末尾添加字符串结尾标志 \0

该函数会返回指向目标字符串 dest 的指针,即拼接后的字符串的起始地址。

需要注意的是,目标字符串 dest 必须有足够的空间来容纳源字符串 src 的字符。否则,会导致缓冲区溢出和未定义的行为。
同时,strncat 不会检查源字符串 src 是否符合 C 字符串的规范(即是否以 \0 结尾),因此要确保源字符串 src 以 \0 结尾,以避免结果不符合预期。

示例 

在这个示例中,我们通过 strncat 函数将源字符串 src 的前 7 个字符拼接到目标字符串 dest 的末尾。输出中的最后一行显示了拼接后的字符串 dest。由于目标字符串 dest 的长度限制在 20 个字符,所以只有部分字符被拼接进去,因此输出结果是 “Hello, Wo”。

#include <stdio.h>
#include <string.h>int main() {char dest[20] = "Hello";const char* src = ", World!";size_t n = 7;printf("目标字符串: %s\n", dest); // 目标字符串: Helloprintf("源字符串: %s\n", src);    // 源字符串: , World!printf("拼接的字符数: %zu\n", n); // 拼接的字符数: 7strncat(dest, src, n);printf("拼接后的字符串: %s\n", dest); // 拼接后的字符串: Hello, Woreturn 0;
}

模拟实现strncat 

#include <stdio.h>char* strncat_sim(char* dest, const char* src, size_t n) {char* dest_start = dest; // 保存目标字符串的起始位置// 遍历目标字符串,直到达到结尾while (*dest != '\0') {dest++;}// 将源字符串中的字符逐个拼接到目标字符串中,直到达到指定的字符数 n 或源字符串结尾while (n > 0 && *src != '\0') {*dest = *src;dest++;src++;n--;}*dest = '\0'; // 添加结尾标记return dest_start; // 返回目标字符串的起始位置
}int main() {char dest[20] = "Hello";const char* src = ", World!";size_t n = 7;printf("目标字符串: %s\n", dest); // 目标字符串: Helloprintf("源字符串: %s\n", src);   // 源字符串: , World!printf("拼接的字符数: %zu\n", n); // 拼接的字符数: 7strncat_sim(dest, src, n);printf("拼接后的字符串: %s\n", dest); // 拼接后的字符串: Hello, Woreturn 0;
}

strncmp

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

  1. 比较字符串: 函数可以比较两个字符串的前n个字符,n由调用函数时指定。
  2. 返回值: 如果 s1 小于 s2,函数返回一个负值;如果 s1 大于 s2,函数返回一个正值;如果两个字符串在前n个字符内相等,函数返回0。
  3. 字符串结束判断: 与标准库中的strncmp类似,如果某个字符串的前n个字符中包含了'\0'(即字符串结束符),则仅比较到该结束符为止。

示例

#include <stdio.h>
#include <string.h>int main() {const char* str1 = "Hello";const char* str2 = "Hell";int n = 4;int result = strncmp(str1, str2, n);if (result == 0) {printf("两个字符串相等\n");} else if (result < 0) {printf("str1 小于 str2\n");} else {printf("str1 大于 str2\n"); // str1 大于 str2}return 0;
}

模拟实现strncmp

#include <stdio.h>int custom_strncmp(const char *s1, const char *s2, size_t n) {for (size_t i = 0; i < n; i++) {if (s1[i] != s2[i]) {return (s1[i] - s2[i]);}if (s1[i] == '\0') {return 0;  // 达到了字符串结尾}}return 0;  // 前 n 个字符均相同
}int main() {const char *s1 = "Hello";const char *s2 = "Hell";int result = custom_strncmp(s1, s2, 4);if (result < 0) {printf("s1 小于 s2\n");} else if (result > 0) {printf("s1 大于 s2\n"); // s1 大于 s2} else {printf("s1 等于 s2\n");}return 0;
}

字符串查找

strstr

查找小串在大串是否出现,返回出现小串往后的字符

char* strstr(const char* haystack, const char* needle);

  1. 主要用途:strstr() 函数经常用于在字符串中查找子串,例如查找某个单词在文本中的位置。
  2. 区分大小写:strstr() 是区分大小写的,即输入的字符串要求大小写完全匹配。
  3. 返回的指针:如果找到了 needle 字符串在 haystack 中的位置,返回的指针指向首次出现的子串;如果未找到,返回 NULL。

示例

    char email[] = "zpw@example.com.demo";char substr[] = "example.com";char *res = strstr(email, substr);if (res == NULL){printf("子串不存在\n");}else{printf("%s", res); // example.com.demo}

模拟实现strstr

char *my_strstr(const char *str1, const char *str2)
{assert(str1 && str2);const char *s1 = str1; // 负责找大串const char *s2 = str2; // 负责找小串const char *p = str1;  // 每次大串的起始点while (*p){s1 = p;s2 = str2;/* 大小串都没结束,并且当前大小串的字符相等则进入 */while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2){s1++;s2++;}/* 如果是因为 小串结束没有再次进到上面循环,那么说明大串中成功找到小串 */if (*s2 == '\0'){return (char *)p;}/* 大串结束了,或者大小串当前字符不相等都会走到这里,则继续++大串的起始查找点,开始下一轮 */p++;}return NULL;
}char email[] = "zpw@example.com.demo";
char substr[] = "example.com";
char *p = my_strstr(email, substr);
printf("%s\n", p); // example.com.demo

strtok

分割字符串

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 指针。

示例

    const char *sep = "@.";char eml[] = "zhanghai@bitejiuyeke.com.net";char cp[40] = {0};strcpy(cp, eml);char *ret = NULL;for (ret = strtok(cp, sep); ret != NULL; ret = strtok(NULL, sep)){/*zhanghaibitejiuyekecomnet*/printf("%s\n", ret);}

模拟实现strtok

#include <stdio.h>
#include <string.h>char* custom_strtok(char* str, const char* delim) {static char* remaining = NULL;if (str != NULL) {remaining = str;}// 跳过开头的分隔符while (*remaining != '\0' && strchr(delim, *remaining) != NULL) {remaining++;}if (*remaining == '\0') {return NULL;}char* token = remaining;remaining = strpbrk(remaining, delim);if (remaining != NULL) {*remaining = '\0';remaining++;}return token;
}int main() {char str[] = "Hello World! This is a test.";char delim[] = " ";char* token = custom_strtok(str, delim);while (token != NULL) {/*HelloWorld!Thisisatest.*/printf("%s\n", token);token = custom_strtok(NULL, delim);}return 0;
}

错误信息报告

strerror

char * strerror ( int errnum );

示例 

在这个示例中,我们尝试打开一个不存在的文件。由于文件不存在,fopen函数将返回NULL。然后,我们使用errno变量获取最近一次错误的错误码,传递给strerror函数。strerror函数将错误码转换为对应的错误信息字符串。

在这里,strerror(errno)将返回"No such file or directory",因为我们尝试打开一个不存在的文件。我们通过printf函数将错误信息打印到控制台上。

#include <stdio.h>
#include <string.h>
#include <errno.h>int main() {FILE* file = fopen("nonexistent_file.txt", "r");if (file == NULL) {printf("Failed to open file: %s\n", strerror(errno));}return 0;
}

字符分类函数

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

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

相关文章

Spring Boot 中使用 ResourceLoader 加载资源的完整示例

ResourceLoader 是 Spring 框架中用于加载资源的接口。它定义了一系列用于获取资源的方法&#xff0c;可以处理各种资源&#xff0c;包括类路径资源、文件系统资源、URL 资源等。 以下是 ResourceLoader 接口的主要方法&#xff1a; Resource getResource(String location)&am…

【Hello Go】Go语言异常处理

Go语言异常处理 异常处理error接口panicrecover延时调用错误问题 异常处理 error接口 Go语言引入了一个关于错误处理的标准模式 它是Go语言内建的接口类型 它的定义如下 type error interface {Error() string }Go语言的标准库代码包errors为用户提供了以下方法 package e…

人工智能轨道交通行业周刊-第65期(2023.10.30-11.19)

本期关键词&#xff1a;高铁自主创新、智慧城轨、调车司机、大模型垂直应用、大模型幻觉 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道…

Kafka快速入门

文章目录 Kafka快速入门1、相关概念介绍前言1.1 基本介绍1.2 常见消息队列的比较1.3 Kafka常见相关概念介绍 2、安装Kafka3、初体验前期准备编码测试配置介绍 bug记录 Kafka快速入门 1、相关概念介绍 前言 在当今信息爆炸的时代&#xff0c;实时数据处理已经成为许多应用程序和…

汽车虚拟仿真视频数据理解--CLIP模型原理

CLIP模型原理 CLIP的全称是Contrastive Language-Image Pre-Training&#xff0c;中文是对比语言-图像预训练&#xff0c;是一个预训练模型&#xff0c;简称为CLIP。该模型是 OpenAI 在 2021 年发布的&#xff0c;最初用于匹配图像和文本的预训练神经网络模型&#xff0c;这个任…

【Ubuntu】设置永不息屏与安装 dconf-editor

方式一、GUI界面进行设置 No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal打开 Ubuntu 桌面环境的设置菜单。你可以通过点击屏幕右上角的系统菜单&#xff0c;然后选择设置。在设置菜单中&#xff0c;…

警惕.360勒索病毒,您需要知道的预防和恢复方法。

引言&#xff1a; 网络威胁的演变无常&#xff0c;.360勒索病毒作为一种新兴的勒索软件&#xff0c;以其狡猾性备受关注。本文将深入介绍.360勒索病毒的特点&#xff0c;提供解决方案以恢复被其加密的数据&#xff0c;并分享一系列强化网络安全的预防措施。如果您在面对被勒索…

Vue中实现div的任意移动

前言 在系统应用中&#xff0c;像图片&#xff0c;流程预览及打印预览等情况&#xff0c;当前视窗无法全部显示要预览的全部内容&#xff0c;设置左右和上下滚动条后&#xff0c;如果用鼠标拖动滚动条&#xff0c;又不太便利&#xff0c;如何用鼠标随意的移动呢&#xff1f; …

wpf devexpress自定义编辑器

打开前一个例子 步骤1-自定义FirstName和LastName编辑器字段 如果运行程序&#xff0c;会通知编辑器是空。对于例子&#xff0c;这两个未命名编辑器在第一个LayoutItem(Name)。和最终用户有一个访客左右编辑器查阅到First Name和Last Name字段&#xff0c;分别。如果你看到Go…

Windows安装nvm【node.js版本管理工具】

目录 下载安装包 安装 配置 配置node的国内镜像源 配置npm的国内镜像源 常用命令 查看可安装的node版本 安装指定的版本 查看已有的node版本列表 切换版本 下载安装包 https://github.com/coreybutler/nvm-windows/releases/tag/1.1.11 安装 安装过程就不贴了&#xff0…

Pytorch D2L Subplots方法对画图、图片处理

问题代码 def show_images(imgs, num_rows, num_cols, titlesNone, scale1.5): #save """绘制图像列表""" figsize (num_cols * scale, num_rows * scale) _, axes d2l.plt.subplots(num_rows, num_cols, figsizefigsize) axes axes.flatten…

sqli-labs关卡19(基于http头部报错盲注)通关思路

文章目录 前言一、回顾上一关知识点二、靶场第十九关通关思路1、判断注入点2、爆数据库名3、爆数据库表4、爆数据库列5、爆数据库关键信息 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚…

滑动窗口练习(一)— 固定窗口最大值问题

题目 假设一个固定大小为W的窗口&#xff0c;依次划过arr&#xff0c; 返回每一次滑出状况的最大值 例如&#xff0c;arr [4,3,5,4,3,3,6,7], W 3 返回&#xff1a;[5,5,5,4,6,7] 暴力对数器 暴力对数器方法主要是用来做校验&#xff0c;不在乎时间复杂度&#xff0c;逻辑上…

Network(四)NAT实现方式与VRRP概述

一 NAT 1 NAT概述 &#xff08;1&#xff09;NAT的作用 Network Address Translation&#xff0c;网络地址转换 通过将内部网络的私有IP地址转换成全球唯一的公网IP地址使内部网络可以连接到互联网。 &#xff08;2&#xff09;私有IP地址分类 A类10.0.0.0~10.255.255.…

云计算(Docker)

Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言&#xff0c;并遵从 Apache2.0 协议开源。它可以让开发者打包应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。Docker 可用于开发…

飞天使-django之数据库简介

文章目录 增删改查解决数据库不能存储中文问题创建表数据类型表的基本操作主键唯一键 unique外键实战 增删改查 四个常用的语句查询 : insert delete update select insert into student(Sno,name) values(95001,"张三") delete from student where name张三 upda…

九、Linux用户管理

1.基本介绍 Linux系统是一个多用户多任务的操作系统&#xff0c;任何一个要使用系统资源的用户&#xff0c;都必须首先向系统管理员申请一个账号&#xff0c;让后以这个账号的身份进入系统 2.添加用户 基本语法 useradd 用户名 应用案例 案例1&#xff1a;添加一个用户 m…

Vue中的watch的使用

先看下Vue运行机制图 那么我们思考一件事&#xff0c;vue是通过watcher监听数据的变化然后给发布-订阅&#xff0c;这样实现了dom的渲染&#xff0c;那么我们思考一件事&#xff0c;我们往往需要知道一个数据的变化然后给页面相应的渲染&#xff0c;那么我们工作中在组件中的数…

可拖动、可靠边的 popupWindow 实现

0 背景 开发要实现一个可以拖动的圆角小窗&#xff0c;要求松手时&#xff0c;哪边近些靠哪边。并且还规定了拖动范围。样式如下&#xff1a; 1 实现 首先把 PopupWindow 的布局文件 pop.xml 实现 <?xml version"1.0" encoding"utf-8"?> <R…

7.22 SpringBoot项目实战【收藏 和 取消收藏】

文章目录 前言一、编写控制器二、编写服务层三、Postman测试最后前言 本系统还支持 收藏图书,就是对心仪的书加一下收藏,大家都懂,这是一个很常见的功能。 那么我们来看看怎么来做,先分析一下:【一个人】对【一本书】只需【收藏一次】,但可以【收藏N本】不同的书,收藏…