进阶C语言——字符串和内存函数

今天我们学点库函数

字符函数和字符串函数

求字符串长度函数->strlen

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
strlen需要的头文件是string.h ,那它的作用是什么呢??
他是来求字符串长度的,统计的是’\0’前的字符串长度

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

size_t是无符号的意思

学会了strlen函数怎么使用,那我们现在模拟实现一下strlen

之前讲过三种方式来实现,大家是否还记得呢?分别是计数的方式,函数递归的方式,还有我们的指针

计数器的方式

#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* arr)
{assert(*arr);int count = 0;while (*arr++){count++;}return count;
}
int main()
{char arr[] = "abcdef";size_t len = my_strlen(arr);printf("%d\n", len);return 0;
}

函数递归

#include<stdio.h>size_t my_strlen(const char* arr)
{if (*arr != 0){return 1 + my_strlen(arr + 1);}}
int main()
{char arr[] = "abcdef";size_t len = my_strlen(arr);printf("%d\n", len);return 0;
}

指针运算

#include<stdio.h>
int my_strlen(char* arr)
{char* str = arr;while (*arr){arr++;}return arr - str;
}
int main()
{char arr[] = "abcdef";int len = my_strlen(arr);printf("%d\n", len);return 0;
}

strcpy函数
在这里插入图片描述
strcpy的作用是把我们的后面字符拷贝到前面字符,但是我们也有相应的前提

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

那我们用代码来看看效果吧

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "xxx";printf("%s", strcpy(arr1, arr2));return 0;
}

在这里插入图片描述
我们可以看到其实我们在拷贝的时候,把’\0‘也拷贝进去,下面再给大家看一个特殊例子
在这里插入图片描述
观察到我们拷贝的时候,是\0之前,这也符合我们上面的规定
现在我们写一个函数来模拟实现这个效果吧

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{assert(*dest && *src);char* ret = dest;while (*dest++ = *src++){;}return dest;
}
int main()
{char arr1[] = "xxxxx";char arr2[] = "abcd";char* arr3 = my_strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}

我们只是模拟实现,不可能实现vs中的strcpy的功能,比如上面我们的代码缺陷就是不能自己copy自己,会存在覆盖现象,导致不能达到我们想要的效果
stract
在这里插入图片描述
源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

这是一个追加的字符串,比如我们要想在arr1字符串后面追加一个hello,这样就可以用我们的strcat

我们用代码看一下它该怎么使用

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

那我们接下来就是模拟实现函数

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* str)
{assert(*dest && *str);char* ret = dest;while (*++dest){;}while (*dest++ = *str++ ){;}return ret;
}
int main()
{char arr1[] = "hello";char arr2[] = " CSDN";char* ret = my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

strcmp
这是一个比较字符串的函数,但是大家可不要误以为是比较长度的,它的作用是比较ASCII的,一个字符一个字符进行比较
在这里插入图片描述
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
所以我们的strcmp函数的返回值应该是整型
下面我们就写个代码看看效果吧

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcde";char arr2[] = "abcdq";int len = strcmp(arr1, arr2);printf("%d", len);return 0;
}

那我们也来模拟实现一下strcmp

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* dest, const char* str)
{assert(*dest && *str);while (*dest == *str && *dest && *str){dest++;str++;}if (dest==NULL){return 0;}return *dest - *str;}
int main()
{char arr1[] = "abcde";char arr2[] = "abcdq";int len = my_strcmp(arr1, arr2);printf("%d", len);return 0;
}

strstr
在这里插入图片描述

#include <stdio.h>
#include <string.h>
int main()
{char str[] = "This is a simple string";char* pch;pch = strstr(str, "simple");if (pch == NULL){printf("找不到\n");}else{printf("找到了\n");}return 0;
}

模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* dest, const char* str)
{assert(dest && str);char* s1 = dest;char* s2 = str;char* cul = dest;while (*cul){s1 = cul;s2 = str;while (*s1 == *s2){s1++;s2++;if (*s2){return cul;}}cul++;}return NULL;
}
int main()
{char str[] = "This is a simple string";char arr[] = "simple";char* p = my_strstr(str, arr);if (p == NULL){printf("找不到\n");}else{printf("找到了\n");}return 0;
}

strstr最大作用就是找这个里面有没有我们想要的字符串,如果有就返回查找字符串内该字符串的地址,如果没有就返回空指针

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 str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}return 0;
}
#include <stdio.h>
int main()
{char *p = "tangjiale@lj.sy";const char* sep = ".@";char arr[30];char *str = NULL;strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep)){printf("%s\n", str);}
}

主要解释第二个代码,因为我们的(str=strtok(arr, sep)只循环一次,这样就可以用for语句来实现,然后strtok是从该内容的后面开始查找,而我们遇到分隔符,其实就相当于变成’\0’,就是空指针,这样我们就写成一个循环,代码优化

strerror

char * strerror ( int errnum );

#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main()
{FILE* pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)printf("Error opening file unexist.ent: %s\n", strerror(errno));//errno: Last error numberreturn 0;
}

在这里插入图片描述
我们的errno就是错误信息,要包含头文件,其实strerror和perror差不多,都是为了找出错误信息,我们也看看perror

在这里插入图片描述

函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母az或AZ
isalnum 字母或者数字,az,AZ,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

以上是一些字符函数的,大家下去一定要试试,这里小编就不一一举例子了

就介绍几个吧

isdigit 十进制数字 0~9
就比如这个,这个的作用就是我们再isdigit只能输入数字,这和while(x>‘0’ && x<‘9’)的效果一样

还有这个

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 (isupper(c)) c=tolower(c);putchar (c);i++;}return 0;
}

在这里插入图片描述
转为小写

memcpy
在这里插入图片描述
模拟实现

void * memcpy ( void * dst, const void * src, size_t count)
{void * ret = dst;assert(dst);assert(src);/** copy from lower addresses to higher addresses*/while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst + 1;src = (char *)src + 1;}return(ret);
}

memmove
在这里插入图片描述
模拟实现

#include<stdio.h>
void* memmove(void* dst, const void* src, size_t count)
{void* ret = dst;if (dst <= src || (char*)dst >= ((char*)src + count)) {while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}}else {dst = (char*)dst + count - 1;src = (char*)src + count - 1;while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst - 1;src = (char*)src - 1;}}return(ret);
}

strncpy
这个其实和strcpy差不多就是加了一个我们拷贝多少字节的内容,我就不过多讲解了

在这里插入图片描述

拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
strncat
在这里插入图片描述

它可以给自己追加

/* strncat example */
#include <stdio.h>
#include <string.h>
int main ()
{char str1[20];char str2[20];strcpy (str1,"To be ");strcpy (str2,"or not to be");strncat (str1, str2, 6);puts (str1);return 0;
}

strncmp

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

在这里插入图片描述

#include <stdio.h>
#include <string.h>
int main ()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts ("Looking for R2 astromech droids...");for (n=0 ; n<3 ; n++)if (strncmp (str[n],"R2xx",2) == 0){printf ("found %s\n",str[n]);}return 0;
}

他的返回值是一个整型

今天的内容就讲完了。我们下次再见,谢谢大家

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

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

相关文章

紫光展锐CEO任奇伟博士:用芯赋能,共建XR新生态

7月6日&#xff0c;2023世界人工智能大会在上海世博中心及世博展览馆盛大开幕。紫光集团高级副总裁、紫光展锐CEO任奇伟博士受邀出席芯片主题论坛&#xff0c;并发表题为《用芯赋能&#xff0c;共建XR新生态》的演讲。 世界人工智能大会自2018年创办以来已成功举办五届&#xf…

1.4 MVP矩阵

MVP矩阵代表什么 MVP矩阵分别是模型&#xff08;Model&#xff09;、观察&#xff08;View&#xff09;、投影&#xff08;Projection&#xff09;三个矩阵。 我们的顶点坐标起始于局部空间&#xff08;Local Space&#xff09;&#xff0c;在这里他成为局部坐标&#xff08;L…

报错:dependencies.dependency.version‘ for com.alibaba:druid:jar is missing

我在pom.xml中是这样写的&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version> </dependency>然后就报错&#xff1a;dependencies.dependency.version for c…

面试题更新之-DOCTYPE html相关问题

文章目录 <!DOCTYPE html>是什么&#xff1f;为什么要在html文件开头加上一个<!DOCTYPE html>DOCTYPE的作用&#xff0c;严格与混杂模式的区别&#xff0c;有何意义HTML5为什么只需要写<!DOCTYPE HTML> 是什么&#xff1f; 是HTML文档的文档类型声明&#xf…

如何拉取GitHub上的不同分支

要拉取GitHub上的不同分支&#xff0c;你可以按照以下步骤进行操作&#xff1a; ①首先&#xff0c;在GitHub上找到你要拉取分支的仓库页面。 ②在仓库页面顶部&#xff0c;你将看到一个下拉菜单&#xff0c;显示当前选择的分支。点击这个下拉菜单&#xff0c;在列表中选择你…

Redis进阶

Redis之父安特雷兹 redis x.x.x第二位是偶数的是稳定版本 redis7安装单机物理机安装&#xff1a; https://blog.csdn.net/G189D/article/details/129185947 数据类型 bitmap 统计二值状态的数据类型 最大位数2^32位&#xff0c;他可以极大的节约存储空间&#xff0c;使用…

postman 自动化测试

postman 自动化测试 0、写在前面1、变量引用1.1、如何在请求体中引用变量 0、写在前面 在有些时候看官方文档 比网上搜索效率要高&#xff0c; 比如网上搜一通还是不知道用法或者没有搜索到你想要的用法的时候。 postman官方文档 : https://learning.postman.com/docs/introdu…

layui选项卡演示

layui选项卡演示 .1 引入layui2. 选项卡演示实列3.js分离的代码4运行结果 在前端开发中&#xff0c;选项卡常用于展示多个内容模块&#xff0c;提供用户友好的界面交互方式。layui作为一款简洁易用的前端框架&#xff0c;提供了丰富的组件库&#xff0c;其中包括了强大且易用的…

J2EEXML建模

目录 用一个xml-config文件实例&#xff1a; 先看config.xml文件 再看 ActionModel ConfigModel ActionNotFoundException ForwardNotFoundException ConfigModelFactory ActionDuplicateDefinitionException ForwardDuplicateDefinitionException InvalidPathExcept…

《MySQL》事务

文章目录 概念事务的操作属性&#xff08;aicd&#xff09; 概念 一组DML语句&#xff0c;这组语句要一次性执行完毕&#xff0c;是一个整体 为什么要有事务&#xff1f; 为应用层提供便捷服务 事务的操作 有一stu表 # 查看事务提交方式(默认是开启的) show variables like au…

【PAT】1022.D进制的A+B

【PAT】1022.D进制的AB 输入两个非负 10 进制整数 A 和 B ( ≤ 2 ​ 30 2​^{30} 2​30​ −1)&#xff0c;输出 AB 的 D (1<D≤10)进制数。 输入格式&#xff1a; 输入在一行中依次给出 3 个整数 A、B 和 D。 输出格式&#xff1a; 输出 AB 的 D 进制数。 输入样例&am…

pytorch深度学习逻辑回归 logistic regression

# logistic regression 二分类 # 导入pytorch 和 torchvision import numpy as np import torch import torchvision from torch.autograd import Variable import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import matplotlib.pyplot as …

Kafka第二课-代码实战、参数配置详解、设计原理详解

一、代码实战 一、普通java程序实战 引入依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.4.1</version></dependency><dependency>&l…

docker 部署网页相关服务

docker 部署网页相关服务 // 安装SFTP 1.拉取镜像 docker pull netresearch/sftp 2.启动后容器&#xff1a; docker run --name Sftp -v E:\wwwroot\julong\fsnfiles:/home/sftpuser/upload --privilegedtrue -p 22:22 -d netresearch/sftp sftpuser:123456:::upload //安装ftp…

Ceph的安装部署

文章目录 一、存储基础1.1 单机存储设备1.2 单机存储的问题1.3分布式存储&#xff08;软件定义的存储 SDS&#xff09; 二、Ceph 简介2.1 Ceph 优势2.2 Ceph 架构2.3 Ceph 核心组件2.4 Pool、PG 和 OSD 的关系&#xff1a;2.5 OSD 存储后端2.6 Ceph 数据的存储过程2.7 Ceph 版本…

面向初学者的卷积神经网络

卷积神经网络在机器学习中非常重要。如果你想做计算机视觉或图像识别任务&#xff0c;你根本离不开它们。但是很难理解它们是如何工作的。 在这篇文章中&#xff0c;我们将讨论卷积神经网络背后的机制、它的优点和应用领域。 什么是神经网络&#xff1f; 首先&#xff0c;让…

架构训练营:3-3设计备选方案与架构细化

3架构中期 什么是备选架构&#xff1f; 备选架构定义了系统可行的架构模式和技术选型 备选方案筛选过程 头脑风暴 &#xff1a;对可选技术进行排列组合&#xff0c;得到可能的方案 红线筛选&#xff1a;根据系统明确的约束和限定&#xff0c;一票否决某些方案&#xff08;主要…

Docker 安装 Nginx,并实现负载均衡

1、获取 nginx 的镜像 # 默认是latest版本docker pull nginx 2、运行 nginx 容器 docker run --name nginx-80 -p 80:80 --rm -d nginx# --name nginx-80 设定容器的名称# -p 80:80 端口进行映射&#xff0c;将本地的80端口映射到容器内部的80端口# --rm 表示容器退出后直接…

GreenPlum on K8s

https://pgconf.in/files/presentations/2019/01-0103-Greenplum_for_Kubernetes_PGConf_India_2019.pdf About the Greenplum Operator | VMware Tanzu Greenplum for Kubernetes Docs VMware Greenplum - Greenplum Database | VMware Tanzu 数据库上云最佳选择—Greenplum…

Vue中v-html用法以及指令汇总

操作数组的方法 &#xff1a; push&#xff1a;数组最后位置新增元素 pop&#xff1a; 删除最后一个元素 shift&#xff1a; 删除第一个元素 unshift&#xff1a;往前面加一个元素 splice&#xff1a;在数组的指定位置插入、删除、替换一个元素 sort&#xff1a; 数组排序…