【C语言】字符函数与字符串函数以及内存函数 { 超详细攻略,一篇学会 }

在这里插入图片描述
今日分享:字符、字符串函数和内存函数
内存函数就是对内存进行操作的函数
字符串函数就是对字符串进行操作的函数
字符函数就是对字符进行操作的函数
str前缀的函数是字符串函数,头文件string.h
mem前缀的函数是内存函数,头文件stdlib.h


字符函数与字符串函数以及内存函数

  • 一、字符分类函数
  • 二、字符转换函数
  • 三、strlen函数
  • 四、strcpy、strncpy、memcpy函数
    • 1、strcpy
    • 2、strncpy
    • 3、memcpy
  • 五、strcat、strncat函数
    • 1、strcat
    • 2、strncat
  • 六、strcmp、strncmp、memcmp函数
    • 1、strcmp
    • 2、strncmp
    • 3、memcmp
  • 七、strstr、strtok、strerror函数
    • 1、strstr
    • 2、strtok
    • 3、strerror
      • perror
  • 八、memmove、memset函数
    • memmove
    • memset

一、字符分类函数

字符分类函数包含在 <ctype.h> 头文件下,专门用来分类字符,如果是则返回非0数字,如果不是返回0
1、iscntrl(int c): 检查是否为控制字符(非打印字符,ASCII码在0x00至0x1F之间,以及0x7F(DEL))
2、isspace(int c): 检查是否为空白字符(空格、制表符、换行符、垂直制表符、换页符和回车符)
3、isdigit(int c): 检查是否为数字(0至9)
4、isxdigit(int c): 检查是否为十六进制数字(0至9,a至f,A至F)
5、islower(int c): 检查是否为小写字母(a至z)
6、isupper(int c): 检查是否为大写字母(A至Z)
7、isalpha(int c): 检查是否为字母(大写或小写)
8、isalnum(int c): 检查是否为字母或数字
9、ispunct(int c): 检查是否为标点符号(除空格和字母数字字符外的可打印字符)
10、isgraph(int c): 检查是否为除空格外的可打印字符
11、isprint(int c): 检查是否为可打印字符(包括空格)

二、字符转换函数

C语言有两个字符转换函数,分别是大写转小写tolower,小写转大写toupper

int tolower(int c);
int toupper(int c);

简单记忆 :
to(变)upper(大写)
to(变)lower(小写)

三、strlen函数

我们在之前的学习中肯定会接触并使用到strlen函数,它的作用是统计字符串中’ \0’ 之前的元素个数,返回值为size_t类型的无符号整型
这个我们就不做过多赘述了,使用方法应该已经深入人心了

四、strcpy、strncpy、memcpy函数

这三个函数都是copy家族的函数,我们放在一起讨论,但字符串函数和内存函数的操作对象不同,适用的范围不同
strcpy和strncpy的返回值都是一个字符指针,指向第一个字符。而memcpy的返回值是void*,因为它可以作用于任意类型的对象,而前面两个智能针对于字符,所以memcpy适用范围更加广泛

1、strcpy

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

strcpy返回值是char*,destination为被操作对象的指针,source为操作对象的指针,将source复制到destination中,destination字符串必须以’\0’结尾,并且足够大,source中的’\0’会被复制到第一个参数中,destination中的内容会被source完全覆盖

#include <stdio.h>
#include <string.h>
int main()
{char s1[256] = "ABCD";char s2[] = "GHAZF";strcpy(s1, s2);printf("%s", s1);return 0;
}

在这里插入图片描述

2、strncpy

在字符串标识str与复制cpy之间加了一个n,表示要复制过去的字符个数
不过它不会完全覆盖,而是将指定相对应的字符复制过去

char* strcpy(char * destination, const char * source, int n);
#include <stdio.h>
#include <string.h>
int main()
{char s1[256] = "ABCD";char s2[] = "GHA";strncpy(s1, s2, 2);printf("%s", s1);return 0;
}

在这里插入图片描述

3、memcpy

void * memcpy ( void * destination, const void * source, size_t num );

函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置,这里的destination可以传任意的地址,可以是数组,也可以是字符串,它都可以进行复制,但这个函数在遇到 ‘\0’ 的时候并不会停下来,所以如果source和destination有任何的重叠,复制的结果都是未定义的。这里我们的最优解就是使用我们后边会说的memmove函数

#include <stdlib.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 6,7,8,9,10};memcpy(arr1, arr2, 2);int sz = sizeof(arr1) / sizeof(arr1[0]);for (int i = 0; i < sz; i++){printf("%d ", arr1[i]);}return 0;
}

在这里插入图片描述

五、strcat、strncat函数

1、strcat

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

#include <stdio.h>
#include <string.h>
int main()
{char s1[256] = "ABCD";char s2[] = "GHA";strcat(s1, s2);printf("%s", s1);return 0;
}

在这里插入图片描述

最好不要自己追加自己
如:

#include <stdio.h>
#include <string.h>
int main()
{char s1[256] = "ABCD";strcat(s1, s1);printf("%s", s1);return 0;
}

在这里插入图片描述
虽然结果与我们预期相同,但我们不建议这样做,我们可以先定义一个中间变量先cpy再cat

2、strncat

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

同strcpy与strncpy的关系:

#include <stdio.h>
#include <string.h>
int main()
{char s1[256] = "ABCD";char s2[] = "GHA";strncat(s1, s2, 2);printf("%s", s1);return 0;
}

在这里插入图片描述
当n值改为4时
在这里插入图片描述
大于source元素个数的话按照最大元素个数来连接

六、strcmp、strncmp、memcmp函数

1、strcmp

第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
第⼀个字符串等于第⼆个字符串,则返回0
第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

int strcmp ( char * destination, const char * source);
#include <stdio.h>
#include <string.h>
int main()
{char s1[] = "ABCD";char s2[] = "ABCD";printf("%d", strcmp(s1, s2));return 0;
}

在这里插入图片描述

2、strncmp

这里不做过多赘述,原理同上,都是有规律可循的

 int strncmp ( const char * str1, const char * str2, size_t num );
#include <stdio.h>
#include <string.h>
int main()
{char s1[] = "ABCD";char s2[] = "ABCE";printf("%d", strncmp(s1, s2, 3));return 0;
}

在这里插入图片描述

3、memcmp

int memcmp ( const void * p1, const void * p2, size_t n );

⽐较从p1和p2指针指向的位置开始,向后的n个字节(任意数据类型)

#include <stdio.h>
#include <string.h>
int main()
{int str1[] = { 1,2,3,4,5 };int str2[] = { 1,2,5,2,1 };printf("%d", memcmp(str1, str2, 4*4));return 0;
}

在这里插入图片描述

七、strstr、strtok、strerror函数

1、strstr

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

char * strstr ( const char * str1, const char * str2);
#include <stdio.h>
#include <string.h>
int main()
{char s1[] = "ABCD";char s2[] = "BC";printf("%p", strstr(s1, s2));return 0;
}

通过调试我们发现,下图图一的地址是s1,也就是首字符’A’的位置,因为是char类型,'B’的位置在’A’的后一位,打印出来的地址就是a+1
图一

图二

2、strtok

sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合。第⼀个参数指定⼀个字符串,它作为你想要用某一符号分隔的标记,符号之间用逗号隔开,它每次找到下一个标记就在这个标记前放一个’\0’然后在这个’\0’后边的第一个元素放一个指针。strtok函数的第⼀个参数若不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置,若第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。如果字符串中不存在更多的标记,则返回 NULL 指针。

char * strtok ( char * str, const char * sep);
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "https://blog.csdn.net/s_little_monster?spm=1000.2115.3001.5343";char* sep = ": , / , . , = , ?";char* str = NULL;for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}

在这里插入图片描述

3、strerror

 char * strerror ( int errnum );

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

将这些信息打印:

#include <stdio.h>
#include <string.h>
#include <errno.h>int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}

在这里插入图片描述

perror

这个函数可以直接打印错误信息,使用方法与strerror相似

(这两个函数作为补充,因为我也不太清楚它们的工作方法)

八、memmove、memset函数

memmove

memcpy的进阶版,它处理的源内存块和⽬标内存块是可以重叠的

void * memmove ( void * destination, const void * source, size_t num );

使用方法和memcpy一样,而且更好用,所以如果要用这个功能的话就用memmove就行

memset

是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。

void * memset ( void * ptr, int value, size_t num );
#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "hello world";memset (str,'9',6);printf(str);return 0;
}

在这里插入图片描述
今天的分享就到这里了~
在这里插入图片描述

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

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

相关文章

C#开发五子棋游戏:从新手到高手的编程之旅

C#开发五子棋游戏&#xff1a;从新手到高手的编程之旅 目录 一、引言 二、项目规划与设计思路 三、棋盘与棋子的数据模型构建 四、交互式用户界面设计 五、核心游戏逻辑实现 一、引言 五子棋&#xff0c;作为一种古老的策略型棋类游戏&#xff0c;在全球拥有广泛的爱好者…

25考研数据结构复习·3.3.2栈和队列的应用——表达式求值

三种算术表达式 中缀表达式 ((15/(7-(11)))*3)-(2(11)) 由三个部分组成&#xff1a;操作数、运算符、界限符 运算符在两个操作数中间&#xff1a;ab&#xff1b;ab-c&#xff1b;ab-c*d ❗后缀表达式 逆波兰表达式 运算符在两个操作数后面&#xff1a;ab&#xff1b;abc-或ab…

python知识点总结(二)

这里写目录标题 1、什么是解释性语言&#xff0c;什么是编译性语言&#xff1f;2、说说中作用域是怎么划分的3、type和isinstance方法的区别4、浅拷贝和深拷贝5、python中变量在内存中存储方式6、python中的封装、继承、多态7、python中内存管理机制是怎么样的&#xff1f;8、简…

旋转中心 机械手抓料方式

一、为什么要计算旋转中心&#xff1f; 机器视觉——旋转中心的标定_旋转标定-CSDN博客 在机械手抓料的时候传送带上过来的料可能是各个角度的&#xff0c;不同的位置&#xff0c;这样如果我们没有做好机械手标定的话很难抓取&#xff0c;因此我们要做旋转中和和机械手TCP标定…

章节2:单词本该这样记

为什么我们记不住单词&#xff1f; 单词不是被胡编乱造出来的&#xff0c;单词是有规律的&#xff0c;单词是符合人类的逻辑的。 单词实际意思结构意义历史文化 我们要怎么记单词&#xff1f; 掌握单词的结构规律了解与单词有关的历史文化灵活巧计&#xff0c;不要太拘泥于…

唯一约束

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 唯一约束 唯一约束的特点是在某一个列上的内容不允许出现重复。 例如&#xff0c;现在要收集用户的信息&#xff0c;假设包含编号&#xff08;mid&#xff09;、姓名&…

【通信原理笔记】【二】随机信号分析——2.3 平稳随机过程的性质

文章目录 前言一、平稳过程的不变性二、平稳过程通过线性时不变系统2.1 输出随机过程的特性2.2 输入输出随机过程的关系 三、平稳过程经过希尔伯特系统总结 前言 在上一篇中我们学习了平稳随机过程这一特殊的随机过程&#xff0c;这篇我们进一步学习平稳过程具有哪些性质。 一…

Word2vec 学习笔记

word2vec 学习笔记 0. 引言1. Word2vec 简介1-1. CBOW1-2. SG 2. 实战 0. 引言 最近研究向量检索&#xff0c;看到有同事使用 MeCab、Doc2Vec&#xff0c;所以把 Word2vec 这块知识学习一下。 1. Word2vec 简介 Word2vec 即 word to vector&#xff0c;顾名思义&#xff0c;…

02python计算与变量

学习目标: 1、计算符号与运算 2、变量的基本使用方法 一、计算符号与运算 Python 中最常用的运算符号有 +(加)、-(减)、*(乘)、/(除)和 %(取余)。 【演示】:在 Python 中进行简单的计算,例如:5 + 3。 在 Python 中,我们可以使用各种运算符号进行数值计算。 …

封装哈希表

本文旨在讲解哈希表的封装&#xff0c;我们以哈希桶的结构来进行封装unorderedmap/set。要想实现封装哈希表&#xff0c;我们首先得先将哈希表的结构给搭建出来&#xff0c;然后再根据哈希桶的结构进一步封装unorderedmap/set&#xff01; 下面我们先来实现哈希桶的结构&#x…

Internet Download Manager(IDM下载) v6.42.3 绿色版介绍

互联网下载管理器是一个广泛使用的软件&#xff0c;它可以帮助用户更好地管理和加速他们的下载。最新版本v6.42.3已经发布&#xff0c;它带来了一系列新功能和改进&#xff0c;让用户更加方便和快速地下载他们需要的文件。 新版本的互联网下载管理器增加了对最新浏览器的支持&…

ROS2+NAV2如何快捷的在docker中使用主机的CAN

驱动底盘一般通过CAN口和底盘通信,在docker中使用CAN最方便的方式就是容器(container)在创建(run)时,指定网络为host模式:--network=host。 例如: docker run -it --restart=always --name ros2humble3 --network=host -v /home/tom/Tom/DockerContent/nav2_ws(your do…

1.Spring入门

1.1 Spring简介 Spring是一个轻量级Java 企业级应用程序开发框架&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架&#xff0c;为开发Java应用程序提供全面的基础架构支持。 Spring Fra…

Linux第80步_使用“信号量”实现“互斥访问”共享资源

1、创建MySemaphoreLED目录 输入“cd /home/zgq/linux/Linux_Drivers/回车” 切换到“/home/zgq/linux/Linux_Drivers/”目录 输入“mkdir MySemaphoreLED回车”&#xff0c;创建“MySemaphoreLED”目录 输入“ls回车”查看“/home/zgq/linux/Linux_Drivers/”目录下的文件…

【git】常用操作

基础操作 git init 初始化仓库 要使用 Git 进行版本管理&#xff0c;必须先初始化仓库&#xff0c; 执行了 git init命令的目录下就会生成 .git 目录。这个 .git 目录里存储着管理当前目录内容所需的仓库数据 git status 查看仓库状态 工作树和仓库在被操作的过程中&#xff0…

C++-线程池

1、使用C构造线程类 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <queue> #include <cstring> #include <time.h> #include <unistd.h> #include <pthread.h> #include <thread> #include &…

Github: Github actions 自动化工作原理与多workflow创建

Github actions 1 &#xff09;概述 Github Actions 是Github官方推出的 CI/CD 解决方案 https://docs.githu.com/en/actions 优点 自动发布流程可减少发布过程中手动操作成本&#xff0c;大幅提升ci/cd效率&#xff0c;快速实现项目发布上线 缺点 存在较高的技术门槛需要利用…

Cloudways搭建WordPress外贸独立站完整教程

现在做个网站不比从前了&#xff0c;搭建网站非常的简单&#xff0c;主要是由于开源的CMS建站系统的崛起&#xff0c;就算不懂编程写代码的人也能搭建一个自己的网站&#xff0c;这些CMS系统提供了丰富的主题模板和插件&#xff0c;使用户可以通过简单的拖放和配置操作来建立自…

使用 Next.js 配置接口跨域

在现代 Web 开发中&#xff0c;跨域请求是一个常见的问题。当我们尝试从一个域&#xff08;例如example.com&#xff09;向另一个域&#xff08;例如api.example.com&#xff09;发送 HTTP 请求时&#xff0c;由于浏览器的同源策略限制&#xff0c;这个请求可能会被阻止。为了解…

制定游戏开发里程碑和迭代周期的最佳实践是什么?

制定游戏开发里程碑和迭代周期是游戏项目管理中的重要环节,以下是最佳实践的几个关键点: 明确项目愿景与目标: 在开始阶段,首先确立游戏的整体愿景、核心玩法以及最终发布的目标。这将为后续的所有里程碑提供方向。定义可度量的里程碑: 里程碑应当具体、清晰且可度量,如完…