【C语言学习笔记---字符串函数】

C语言程序设计笔记---018

  • C语言字符串函数
    • 1、字符串函数
      • 1.1、strlen函数
      • 1.2、strcpy函数
      • 1.3、strcat函数
      • 1.4、strcmp函数
      • 1.5、strncpy函数
      • 1.6、strncat函数
      • 1.7、strncmp函数
      • 1.8、strstr函数
      • 1.9、strtok函数
      • 1.10、strerror函数
    • 2、字符分类函数
      • 2.1、islower函数
      • 2.2、isdigit 和 isxdight函数
      • 2.3、islower 和 isupper函数
    • 3、字符转换函数
      • 3.1、tolower函数
      • 3.2、toupper函数
    • 4、结语

C语言字符串函数

前言:
通过C语言指针进阶的知识,接下来继续学习关于C语言哪些实用的函数呢?

/知识点汇总/
字符串函数分类
1.求字符串长度:strlen
2.长度不受限制的字符串函数:strcpy、strcat、strcmp
3.长度受限制的字符串函数:strncpy、strncat、strncmp
4.字符串查找函数:strstr、strtok
5.错误信息报告函数:strerroe、perror
6.字符分类函数:
iscntrl – 任何控制字符
isspace – 空白字符:‘空格’,换页’\f’,回车’\n’,制表符’\t’.
isdigit — 十进制数字0~9
isxdigit – 十六进制数字 ,包括十进制数字,小写字母af,大写字母AF
islower — 小写字母a~z
isupper — 大写字母A~Z
isalpha – 字母az或AZ
isalnum – 字母或数字 ,az,AZ,0~9
ispunct – 标点符号,任何不属于数字或者字母的图形字符
isgraph – 任何图形字符
7.字符转换函数:
int tolower (int c); — 大写转小写字母
int toupper (int c); — 小写转大写字母
(这里把1~6的函数归纳到字符串函数里讲解)

1、字符串函数

1.1、strlen函数

库函数:用来求字符串长度的库函数,本质上统计的是字符串中’\0’之前的字符个数
原型:size_t strlen( const char *string );
头文件:#include <string.h>

#include <stdio.h>
#include <string.h>
int main()
{size_t len1 = strlen("abcdef");//等价,其中传参传递的首元素地址const char* str = "abcdef";size_t len2 = strlen(str);printf("%d\n", len1);//6printf("%d\n", len2);//6//另外得注意,字符串本身就放置了'\0'的情况size_t len1 = strlen("abc\0def");const char* str = "abc\0def";size_t len2 = strlen(str);printf("%d\n", len1);//3printf("%d\n", len2);//3return 0;
}

补充size_t 的特点:

#include <stdio.h>
#include <string.h>int main()
{if (strlen("abc") - strlen("abcdef") > 0)//因为strlen的返回值是无符号数//两个无符号数相减得到的依然是无符号数//相等于即使相减为负数,但是返回值会约束其符号位无效了,从而成为一个很大的数远远大于0printf(">=0\n");elseprintf("<=0\n");return 0;
}

1.2、strcpy函数

功能:完成字符串的拷贝,将原目标字符串地址拷贝到目标字符串地址。
原型:char *strcpy( char *strDestination, const char *strSource );
头文件:#include <string.h>

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

使用strcpy几个注意事项
1.源字符串必须以’\0’结束(因为会包括’\0’一起拷贝过去)
2.会将源字符串中的’\0’拷贝到目标空间
3.目标空间必须足够大,确保能存放源字符串
4.目标空间必须可变(不能是常量)
5.学会模拟实现,才能更好掌握

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

小结:所以是由程序员决定目标空间必须足够大,且目标空间必须权限为可写

1.3、strcat函数

功能:将源头的字符串地址追加到目标字符串的地址
原型:char *strcat( char *strDestination, const char *strSource );
头文件:<string.h>
执行步骤
1.找到arr1的末尾’\0’
2.再把arr1的内容追加到arr1后边(arr2的首地址会覆盖,arr1的’\0’实现追加)

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

注意事项
1.目标空间足够大
2.目标空间必须有’\0’(保证能找到目标空间的末尾)
3.源字符串也得有’\0’,拷贝时会一通拷贝过去,从而组成新字符串得结束位标志符
4.自己追加自己时,源指针和目标指针都指向首字符,然后源字符串的’\0’,会被覆盖掉,导致后面追加时,找不到’\0’了。尽管库函数能实现,但是不建议

1.4、strcmp函数

功能:字符串比较大小(不是比较长度,而是比较对应位置上的字符大小,即ASCII码值)
原型:int strcmp( const char *string1, const char *string2 );
头文件:<string.h>
Return Value
Value Relationship of string1 to string2
//< 0 string1 less than string2
//0 string1 identical to string2
//> 0 string1 greater than string2
标准规定:比较ASCLL码值
1.第一个字符串大于第二个字符串,则返回大于0的数字
2.第一个字符串等于第二个字符串,则返回0
3.第一个字符串小于第二个字符串,则返回小于0的数字

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abq";int ret = strcmp(arr1, arr2);printf("%d\n", ret);//-1,第一个字符串比第二个字符串小,返回小于零的数值return 0;
}

小结
strlen,strcat,strcmp,strcpy属于长度不受限制的字符串函数;
接着介绍长度受限制字符串函数:strncat,strncmp,strncpy

1.5、strncpy函数

功能:字符串拷贝(可指定长度)
原型:char* strncpy(char* strDest, const char* strSource, size_t count);
头文件:<string.h>

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = { 0 };char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);//abcchar arr1[20] = "xxxxxxxxxxxxxxx";char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);//abcxxxxxxxxxxreturn 0;
}

探讨拷贝长度的影响

#include <stdio.h>
#include <string.h>int main()
{char arr1[20] = "xxxxxxxxxxxx";char arr2[] = "abc";strncpy(arr1, arr2, 6);//长度比str2长时,自动补的'\0'.printf("%s\n", arr1);//abc\0\0\0return 0;
}

1.6、strncat函数

功能:字符串追加(可指定长度)
原型:char* strncat(char* strDest, const char* strSource, size_t count);
头文件:<string.h>

#include <stdio.h>
#include <string.h>int main()
{char arr1[20] = "abc";char arr2[] = "defghi";strncat(arr1, arr2, 3);//长度比str2长时,自动补的'\0'.printf("%s\n", arr1);//abcreturn 0;
}

探究’\0’的追加情况1:

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc\0xxxxxxxxxxx";//字符串中本身具备'\0'时,依然以'\0'开始覆盖,最后补'\0'结束char arr2[] = "defghi";strncat(arr1, arr2, 3);printf("%s\n", arr1);//abcdef\0return 0;
}

探究’\0’的追加情况2:

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc\0xxxxxxxxxxx";//字符串中本身具备'\0'时,依然以'\0'开始覆盖,最后补'\0'结束char arr2[] = "defghi";strncat(arr1, arr2, 10);//10长度比str2长时,自动在末尾补'\0'.此函数就不会对超出长度的字符进行操作了printf("%s\n", arr1);//abcdefreturn 0;
}

1.7、strncmp函数

功能:字符串大小比较(可指定长度)
原型:int strncmp( const char *string1, const char *string2, size_t count );
头文件:<string.h>

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abcqw";//int ret = strncmp(arr1, arr2, 3);//printf("%d\n", ret);//0int ret = strncmp(arr1, arr2, 4);//比较字符串前4个字符printf("%d\n", ret);//-1return 0;
}

1.8、strstr函数

功能:在字符串中找字符串(字符串中找子字符串或着段),strstr会返回str1中str2第一次出现的位置,如果str1中没有str2,则返回NULL
原型:const char *strstr( const char *string, const char *strCharSet );
头文件:<string.h>

#include <stdio.h>
#include <string.h>int main()
{char arr1[] = "abcdefghi";char arr2[] = "def";char* ret = strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);//defghi}return 0;
}

1.9、strtok函数

功能:常用于切割字符串
原型:char *strtok( char *strToken, const char *strDelimit );
头文件:<string.h>

注意
strtok函数找到str中的下一个标记,并将其用’\0’,结尾返回一个指向这个标记的指针;
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。
比如
IP地址:本来是一个无符号的整数,这种整数不方便记忆,所以将这个整数转换成点分十进制的表示方式
abcdef@yeah.net – 分隔符可以是@或 ’ . ’
192.168.101.23 – 分隔符可以是 ’ . ’

#include <stdio.h>
#include <string.h>int main()
{char arr[] = "abcdef@yeah.net";char* p = "@.";char* s = strtok(arr, p);//将被标记的地方改为'\0',再把'\0'之前的切分出来。printf("%s\n", s);return 0;
}

小结:在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改
如下所示,利用一个新数组保存原数组数据:

#include <stdio.h>
#include <string.h>int main()
{char arr[] = "abcdef@yeah.net";char buf[200] = { 0 };strcpy(buf, arr);char* p = "@.";char* s = strtok(buf, p);//将被标记的地方改为'\0',再把'\0'之前的切分出来。printf("%s\n", s);return 0;
}

小结
strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回NULL指针。

如下所示,每次调用都会保存上次调用的标记(具备记忆功能),依次类推:

#include <stdio.h>
#include <string.h>int main()
{char arr[] = "abcdef@yeah.net";char buf[200] = { 0 };strcpy(buf, arr);char* p = "@.";char* s = strtok(buf, p);//将被标记的地方改为'\0',再把'\0'之前的切分出来。printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);return 0;
}

为了代码的实用性,以循环的方式依次识别标记,对代码进行优化

#include <stdio.h>
#include <string.h>int main()
{char arr[] = "abcdef@yeah.net";char buf[200] = { 0 };strcpy(buf, arr);char arr2[] = "192.168.101.23";char buf2[200] = { 0 };strcpy(buf2, arr2);char* p = "@.";char* s = NULL;for (s = strtok(buf, p); s != NULL; s = strtok(NULL, p)){printf("%s\n", s);}char* p2 = ".";for (s = strtok(buf2, p2); s != NULL; s = strtok(NULL, p2)){printf("%s\n", s);}return 0;
}

小结
1.strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。
2.strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
3.strtok函数的第一个参数为NULL,函数将在同一个字符串中将被保存的位置开始,查找下一个标记。
4.如果字符串中不存在更多的标记,则返回标记为NULL指针

1.10、strerror函数

功能:是将错误码翻译成错误信息,返回错误信息的字符串的起始地址
原型:char *strerror( int errnum );
头文件:<string.h>

错误码比如常见网页打不开显示:-404-
C语言中使用库函数的时候,如果发生错误,就会将错误码放在errno的变量中,errno是一个全局变量,可以直接使用的

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

strerror函数常用于文件的操作判定
以打开文件的例子展示:
fopen以读的形式打开文件,如果文件存在,打开成功;如果文件不存在,打开失败。

#include <stdio.h>
#include <string.h>int main()
{FILE* pf = fopen("add.txt", "r");if (pf == NULL){printf("打开文件失败,原因是:%s\n",strerror(errno));return 1;}else{printf("打开文件成功\n");}return 0;
}

对比perroe函数
原型:void perror( const char *string );
功能:直接打印错误码,所对应的错误信息(先打印自定义信息:xxx,再直接打印错误原因)
等价:perror == printf + strerror

#include <stdio.h>
#include <string.h>int main()
{FILE* pf = fopen("add.txt", "r");if (pf == NULL){perror("打开文件失败");return 1;}else{printf("打开文件成功\n");}return 0;
}

2、字符分类函数

字符分类函数:
iscntrl – 任何控制字符
isspace – 空白字符:‘空格’,换页’\f’,回车’\n’,制表符’\t’…
较常用:
isdigit — 十进制数字0~9
isxdigit – 十六进制数字 ,包括十进制数字,小写字母af,大写字母AF
islower — 小写字母a~z
isupper — 大写字母A~Z
isalpha – 字母az或AZ
isalnum – 字母或数字 ,az,AZ,0~9
ispunct – 标点符号,任何不属于数字或者字母的图形字符
isgraph – 任何图形字符

这里以常见的为例

2.1、islower函数

原型:int iswlower( wint_t c );
头文件:<ctype.h>
功能:判断字符是否为小写字母,如果为小写,则返回非零的值;如果不是小写,则返回0

#include <stdio.h>
#include <ctype.h>int main()
{char ch = 'a';if (islower(ch)){printf("是小写\n");}else{printf("不是小写\n");}return 0;
}

2.2、isdigit 和 isxdight函数

原型:int isdigit( int c );
头文件:<ctype.h>
功能:判断字符是否为十进制数字0~9

原型:int isxdigit( int c );
头文件:<ctype.h>
功能:判断字符是否为十六进制数字 ,包括十进制数字,小写字母af,大写字母AF

#include <stdio.h>
#include <ctype.h>
int main()
{//if(ch >= 'a' && ch <= 'z')int ret = islower('a');printf("%d\n", ret);int ret2 = isdigit('5');printf("%d\n", ret2);int ret3 = isxdigit('c');printf("%d\n", ret3);return 0;
}

2.3、islower 和 isupper函数

原型:int islower( int c );
头文件:<ctype.h>
功能:判断字符是否为小写字母a~z

原型:int isupper( int c );
头文件:<ctype.h>
功能:判断字符是否为大写字母A~Z

#include <stdio.h>
#include <ctype.h>int main()
{char ch1 = 'A';char ch2 = 'a';if(islower(ch2))printf("小写字母:%c\n",ch2);if(islower(ch1))printf("大写字母:%c\n",ch1);return 0;
}

3、字符转换函数

C语言只有两个字符转换函数:tolower 、toupper

3.1、tolower函数

原型:int tolower( int c );
头文件:<ctype.h>
功能:将大写字母转换为小写字母

#include <stdio.h>
#include <ctype.h>int main()
{char arr[] = "TEST String.";char* p = arr;while (*p){if (isupper(*p)){*p = tolower(*p);}p++;}printf("%s\n", arr);return 0;
}

3.2、toupper函数

原型:int toupper( int c );
头文件:<ctype.h>
功能:将小写字母转换为大写字母

#include <stdio.h>
#include <ctype.h>int main()
{int ret = tolower('A');printf("%c\n", ret);//aint ret2 = toupper('a');printf("%c\n", ret2);//Aint ret3 = tolower('A');printf("%c\n", ret3);//aret3 = toupper(ret3);printf("%c\n", ret3);//Areturn 0;
}

4、结语

熟悉各个函数的使用有利于程序的可读性和效率,此篇笔记有误的地方请多多指教。
半亩方糖一鉴开,天光云影共徘徊。
问渠哪得清如许?为有源头活水来。–朱熹(观书有感)

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

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

相关文章

docker镜像相关

docker镜像相关 docker镜像相关理解解释unionFS&#xff08;联合文件系统&#xff09;镜像加载原理docker镜像要采用这种分层结构 重点理解docker镜像commit 操作实例案例演示总结 docker镜像相关理解 解释 镜像是一种轻量级&#xff0c;可执行的独立软件包&#xff0c;它包含…

Vue基础知识点(面试可用):v-if和v-show的区别

① 简述v-if和v-show的区别&#xff1f; v-if 在编译过程中会被转化成三元表达式&#xff0c;条件不满足时不渲染此节点。元素销毁和重建控制显示隐藏。 v-show 会被编译成指令&#xff0c;条件不满足时控制样式将此节点隐藏&#xff08;display:none&#xff09; css样式控制…

【Datawhale课程笔记-简单学点大模型】模型架构

模型架构 参考地址&#xff1a;https://github.com/datawhalechina/so-large-lm/blob/main/第七章&#xff1a;模型架构.md 大模型之模型概括 语言模型的一开始就可以被看做是一个黑箱&#xff0c;当前大规模语言模型的能力在于给定一个基于自身需求的prompt就可以生成符合需…

Redis学习笔记--002

Redis的JAVA客户端 文章目录 Redis的JAVA客户端一、Redis的Java客户端的种类二、Jedis2.1、使用步骤2.2、Jedis连接池 三、[SpringDataRedis](https://spring.io/projects/spring-data-redis)3.1、介绍3.2、RedisTemplate3.3、SpringDataRedis使用步骤3.4、SpringDataRedis的序…

RabbitMQ工作模式——PubSub生产者及消费者

PubSub模式生产者代码 public class Producer_PubSub {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工厂ConnectionFactory factory new ConnectionFactory();//2.设置参数factory.setHost("172.16.98.133"); ip 默…

JavaWeb 学习笔记 8:AJAX

JavaWeb 学习笔记 8&#xff1a;AJAX AJAX&#xff08;Asynchronous JavaScript And XML&#xff0c;异步 js 和 XML&#xff09;是一种用 js 代码异步&#xff08;或同步&#xff09;的方式请求服务端数据&#xff0c;并在页面显示或加载的技术。 1.快速入门 先看如何用纯 …

STM32-无人机-电机-定时器基础知识与PWM输出原理

电机控制基础——定时器基础知识与PWM输出原理 - 掘金单片机开发中&#xff0c;电机的控制与定时器有着密不可分的关系&#xff0c;无论是直流电机&#xff0c;步进电机还是舵机&#xff0c;都会用到定时器&#xff0c;比如最常用的有刷直流电机&#xff0c;会使用定时器产生PW…

Linux学习记录——삼십 socket编程---udp套接字

文章目录 UDP套接字简单通信1、服务端1、创建文件&#xff0c;写框架2、用命令行参数调起程序3、服务端运行逻辑 2、客户端1、创建套接字2、发送数据 3、测试4、通信5、加功能1、处理数据2、群聊 6、Windows下socket编程的不同 UDP套接字简单通信 1、服务端 1、创建文件&…

【C语言学习笔记---内存函数】

C语言程序设计笔记---019 C语言进阶之内存函数1、memcpy函数1.1、模拟实现memcpy 2、memmove函数2.1、模拟实现memmove函数 3、memset函数4、memcmp函数5、结语 C语言进阶之内存函数 前言&#xff1a; 通过C语言进阶前篇的字符串函数的知识&#xff0c;继续C语言的内存函数学习…

vue+element plus 使用table组件,清空用户的选择项

<el-table ref"tableRef"> .... </el-table> <script lang"ts" setup> import { onMounted, reactive, ref, nextTick } from vue const clearBtn () > {console.log(清空用户的选择项)tableRef.value.clearSelection() } </scr…

基于Java的酒店管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

洛谷P5660:数字游戏 ← CSP-J 2019 复赛第1题

【题目来源】https://www.luogu.com.cn/problem/P5660https://www.acwing.com/problem/content/1163/【题目描述】 小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏&#xff0c;小 P 同学想要知道字符串中究竟有多少个 1。 注意&#xff1a;01 字符串为每一个…

docker alpine:3.16 root权限安装Anaconda3-2020.07-Linux-x86_64和jdk

首先查看系统版本: rootfv-az454-287:/tmp# uname -a Linux fv-az454-287 5.15.0-1046-azure #53~20.04.1-Ubuntu SMP Mon Aug 28 14:17:23 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux rootfv-az454-287:/tmp# grep NA /etc/os-release NAME"Ubuntu" PRETTY_NAME&q…

【VIM安装ctags cscope】

一、安装软件包 sudo passwd root sudo apt install cmake python2-dev python3-dev build-essential cmake flex bison -y sudo apt install universal-ctags cscope vim git -y sudo apt install python-is-python3 -y sudo apt-get install build-essential libncurses-dev…

算法 - 栈和队列

算法 - 栈和队列 算法 - 栈和队列 栈 1. 数组实现2. 链表实现 队列 栈 public interface MyStack<Item> extends Iterable<Item> {MyStack<Item> push(Item item);Item pop() throws Exception;boolean isEmpty();int size();}1. 数组实现 public class A…

在c#中使用CancellationToken取消任务

目录 &#x1f680;介绍&#xff1a; &#x1f424;简单举例 &#x1f680;IsCancellationRequested &#x1f680;ThrowIfCancellationRequested &#x1f424;在控制器中使用 &#x1f680;通过异步方法的参数使用cancellationToken &#x1f680;api结合ThrowIfCancel…

Docker Compose初使用

简介 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#xff09;以及容器&#xff08;cont…

【论文阅读 09】融合门控自注意力机制的生成对抗网络视频异常检测

2021年 中国图象图形学报 摘 要 背景&#xff1a; 视频异常行为检测是智能监控技术的研究重点&#xff0c;广泛应用于社会安防领域。当前的挑战之一是如何提高异常检测的准确性&#xff0c;这需要有效地建模视频数据的空间维度和时间维度信息。生成对抗网络&#xff08;GANs&…

langchain +gpt 报错 SSLError

解决版本2种 一加入下面代码: https://www.zhihu.com/question/588395420 import os os.environ["http_proxy"] "http://127.0.0.1:7890" os.environ["https_proxy"] "http://127.0.0.1:7890"二降低urllib3版本 urllib3 1.25.11错…

Stable Diffusion 系统教程 | 强大的ControlNet 控制网

2023年的2月13日&#xff0c;一款名叫ControlNet的插件横空出世&#xff0c;AI绘画变得更加可控 ControlNet直译过来很简单&#xff0c;就叫做控制网&#xff0c;开发者是一名华裔&#xff0c;毕业于苏州大学&#xff0c;目前在斯坦福做读博士一年级&#xff0c;大佬大佬&…