首页 > 其他分享 >【C语言】字符函数和字符串函数

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

时间:2024-08-10 21:28:57浏览次数:8  
标签:1111 函数 指向 字符 C语言 char 字符串

目录

一、字符函数

(1)字符分类函数

(2)字符转换函数

二、字符串函数

(1)strlen

① 函数原型

② 注意事项

③ 模拟实现函数

(2)strcpy

① 函数原型

② 注意事项

③ 模拟实现函数

(3)strcat

① 函数原型

② 注意事项

③ 模拟实现函数

(4)strcmp

① 函数原型

② 模拟实现函数

(5)strncpy

① 函数原型

② 注意事项

③ 模拟实现函数

(6)strncat

① 函数原型

② 注意事项

③ 模拟实现函数

(7)strncmp

① 函数原型

② 注意事项

(8)strstr

① 函数原型

② 注意事项

③ 模拟实现函数

(9)strtok

① 函数原型

② 使用示范

(10)strerror

① 函数原型

② 使用示范

(11)perror


一、字符函数

        这些函数的都包含在头文件<ctype.h>里,参考:<cctype> (ctype.h) - C++ Reference (cplusplus.com)

(1)字符分类函数

        字符有数字字符、字母字符等,有时候需要区分字符的类别,就可以用这些函数:

6fd91347747a40b999159d7ee57ff2ad.png

        如果参数符合判断的字符类别,就返回非0值,否则返回0。

(2)字符转换函数

        字符转换函数就是将字母字符转大小写的:

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写 
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

        如果传入的参数不符合要求,比如传入 '!',那么就不会对参数进行处理。

二、字符串函数

        字符串的函数都包含在<string.h>头文件中,参考:<cstring> (string.h) - C++ Reference (cplusplus.com)

(1)strlen

① 函数原型

        该函数的作用是计算字符串的长度。

size_t strlen ( const char * str );

② 注意事项

  • 从指定位置开始,到 '\0' 结束,统计 '\0' 之前的字符个数。因此,参数必须有 '\0'。
  • 返回值是 size_t 无符号整数(长度没有负数),这是一个易错点。例如,看看下面代码的结果是什么?

448fa8b6d46b4600b91a4b3a27575262.png

        正确结果是打印">=",很容易错误地认为打印'<',原理如下:

        strlen(s1)返回值3,strlen(s2)返回值6,3-6=-3,但左边结果为无符号整数,右边0默认是有符号整数,根据算术转换规则,会将右边的有符号整数0转换为无符号整数。

[-3]有符号整数

= [1000 0000 0000 0000 0000 0000 0000 0011]原

= [1111 1111 1111 1111 1111 1111 1111 1100]反

= [1111 1111 1111 1111 1111 1111 1111 1101]补

= [1111 1111 1111 1111 1111 1111 1111 1101]无符号整数原

= 4294967293

        结果是左边的值大于右边的0,打印">="。

        因此,对于用strlen判断两个字符串的长度,最好这样用:

if( strlen(s1) > strlen(s2) ){
    ;
}

// 或者

if( (int)strlen(s1) - (int)strlen(s2) > 0 ){
    ;
}

③ 模拟实现函数

        方法1:计数器

d55c1006db274146a77ca6d659590361.png

        方法2:指针 - 指针

8a735bfb4f0b4bc1aac5ecfb1f0bb4f0.png

        方法3:递归

9fb756e1a03145a3b68f0cac5fef498f.png

(2)strcpy

① 函数原型

        该函数的作用是将源字符串(source)拷贝到目标字符串(destination)中。

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

② 注意事项

  • 以源字符串中的 '\0' 作为拷贝结束的标志,'\0'也会复制到目标字符串中。因此,源字符串必须含有 '\0'。否则,会越界拷贝,直到遇到 '\0' 结束。
  • 目标字符串的空间必须足够大,至少要不能小于源字符串的空间大小。
  • 目标字符串必须可修改,才能拷贝字符到里面。因此不能用 const 修饰。
  • 返回值是拷贝好后的目标字符串的首字符地址。有返回值的原因,是给用户更好的体验,比如能够实现链式调用:

32210134239c49019d511f034eb157be.png

  • 以下几种写法都是错误的:

6c0993f58eca4361bf975ae57f25095c.png

1e73b2127972454c99b04b327a69f54d.png

③ 模拟实现函数

921f5f4b74bd4e2a82123006c9cbd1f2.png

(3)strcat

① 函数原型

        该函数的作用是将源字符串追加到目标字符串的末尾。

char *my_strcat(char *dest, const char*src);

② 注意事项

  • 从目标字符串的 '\0' 开始(拷贝内容会把目标字符串结尾的 '\0'覆盖掉),将源字符串拷贝到目标字符串中,直到将源字符串中的 '\0' 也拷贝进去。因此,源字符串和目标字符串,都必须有 '\0'。
  • 目标字符串的空间要足够大,能容下拷贝后的内容。
  • 目标字符串的空间必须可修改,不能用const修饰。
  • 不能自己追加自己,原因如下:

5e5813838fa84a608abb21c8b3b3c3c5.png

        根据C标准,strcpy是不能自己追加自己的,但是VS实现的strcpy能自己追加自己。我们以C标准为准,因为不是所有的编译器实现的库函数都能自己追加自己。

③ 模拟实现函数

b9b51a07a51b43c1a6ed79e467e6b75a.png

(4)strcmp

① 函数原型

        它的功能是比较 str1 和 str2 指向的字符串大小,通过比较两个字符串对应位上的字符的ASCII码来实现。

        str1 大于 str2 指向的字符串则返回值大于0;str1 等于 str2 指向的字符串则返回值等于0;str1 小于 str2 指向的字符串则返回值小于0。

        例如比较 "abc" 和 "abcd",前三个字符都相同,第四位字符是将 '\0' 和 'd'进行比较,对应ASCII码是 0 < 100,因此 "abc" 小于 "abcd"。

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

② 模拟实现函数

        接下来要学习strncpy、strncat、strncmp函数,它们会限制操作的字符串长度;而strcpy、strcat、strcmp不同的是,它们不限制操作的字符串长度,直到字符串结尾为止。

(5)strncpy

① 函数原型

        它的作用是,将源字符串的前n个字符拷贝到目标字符串中。

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

② 注意事项

  • 如果源字符串长度小于num,且源字符串结尾没有'\0',在拷贝完源字符串后,会越界拷贝,因此源字符串结尾必须有'\0'。

  • 如果源字符串长度小于num,在拷贝完源字符串后,会在目标字符串后追加 ‘\0’ ,直到达到num个。

  • 如果源字符串长度大于num,拷贝完前num个字符后,不会在结尾追加'\0'。

③ 模拟实现函数

(6)strncat

① 函数原型

        它的作用是将源字符串的前num个字符追加到目标字符串末尾,并追加一个'\0'。

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

② 注意事项

  • 若源字符串长度小于num,则只会将源字符串(包括\0)追加到目标字符串中,不会追加其它的字符。

  • 当num小于源字符串长度时,在追加完前num个字符后,会在结尾再追加一个'\0'。

  • 因为能控制追加的字符个数,所以可以解决strcat不能自己追加自己的问题。

③ 模拟实现函数

(7)strncmp

① 函数原型

        它的作用是最多比较str1和str2指向的字符串的前num个字符的大小。

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

② 注意事项

        如果num大于本该比较的长度,则按本该比较的长度来。

        这时并不是比较s1和s2的前8个字符,而是比较到 "ab" 结尾的 '\0' 为止。

(8)strstr

① 函数原型

        它的作用是:如果str2是str1的子串,则返回str2在str1中第一次出现的位置;如果str2不是str1的子串,则返回NULL。

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

② 注意事项

        字符串的比较不包含'\0',但以'\0'为结束标志。

        比如返回 “bba” 在 "aabbaa" 中第一次出现的位置,不会比较"bba"结尾的 '\0',但是会因为'\0'而结束比较,此时表示匹配成功;比如返回"nba" 在 "abcd"中第一次出现的位置,因为"abcd"里没有"nba",所以比较完 "abcd" 的 'd' 和 "nba" 的 'n'后,是"abcd"的最后一个字符'\0',到此结束所有比较,匹配失败。

③ 模拟实现函数

        s1和s2分别指向字符串str1和str2当前比较的字符地址。cur用于指向字符串str1的当前比较的子串首字符地址,便于在这个子串不匹配时,立马比较下一个子串,即s1指向cur的下一个字符开始比较。str2用来保存str2的首字符地址,在当前子串匹配失败时,s2立即返回到str2。

        比较s1指向的a和s2指向的b,不匹配,cur更新为自增1,s1指向cur的位置(下面子串结尾的\0画掉了,自行脑补):

        比较s1指向的b和s2指向的b,匹配,s1和s2分别指向下一个字符:

        比较s1指向的b和s2指向的a,不匹配,cur自增1,s1指向cur的位置,s2回到str2:

        比较s1指向的b和s2指向的b,匹配,s1和s2分别指向下一个字符:

        比较s1指向的a和s2指向的a,匹配,s1和s2分别指向下一个字符:

        比较s1指向的a和s2指向的a,匹配,s1和s2分别指向下一个字符:

        子串的s2指向的 '\0',匹配成功,返回指针cur。

        如果子串str2不在str1里面,s2一直不能指向'\0',那么cur就会一直加加,直到cur指向'\0',则返回NULL。

(9)strtok

① 函数原型

char * strtok ( char * str, const char * sep);
  • sep指向一个字符串,里面是一些分隔符。
  • str指向一个字符串,里面是一些被sep中的0到多个分隔符分割的0到多个标记。
  • strtok找到str中的下一个标记后,会将其结尾的分隔符替换成'\0',并返回这个标记的首字符地址。(因为strtok会改变str的内容,我们又不希望改变原字符串的内容,所以传给str的通常是原字符串的拷贝内容,并且这个拷贝的内容是允许被修改的。)

  • 如果strtok函数的str参数不为NULL,将找到str中的第一个标记,并把标记的位置保存下来。
  • 如果strtok函数的str参数为NULL,将找到同一个字符串中保存的位置的下一个标记,并把标记的位置保存下来。
  • 当字符串中没有更多标记时,strtok函数返回NULL。

② 使用示范

        这个函数看着挺奇怪,str只需要第一次传给它,后面传NULL就能根据保存的位置找到下一个标记。但是在之前学过,函数在调用结束后会将局部变量的空间销毁,那这个位置是怎么保存的?每次更改后的str又是怎么保留下来的?我们可以大胆猜测,里面肯定有static修饰的变量,这样就能把这些变量的生命周期改为跟运行的程序的生命周期一样长了。

(10)strerror

① 函数原型

        它的作用是返回错误码errnum对应的错误信息的字符串地址。

 char* strerror ( int errnum );

        在一些系统和C语言标准库中都定义了一些错误码,这些错误码一般在<errno.h>头文件中说明。程序运行时会定义一个全局变量 errno,来记录当前的错误码。程序一开始运行时,errno初始化为0,表示没有错误;当调用标准库中的函数发生错误时,就会将errno赋值为错误对应的错误码。因为错误码只是一个整数,我们无法理解它代表的意思,所以strerror函数可以返回错误码对应的错误信息字符串的地址,帮助我们知道当前发生了什么错误。

② 使用示范

(11)perror

        perror == print + error,功能就是直接打印errno对应的错误信息。输出到屏幕的结果是:参数中的字符串 + 一个冒号 + 一个空格 + 错误信息。

标签:1111,函数,指向,字符,C语言,char,字符串
From: https://blog.csdn.net/2401_86272648/article/details/141034701

相关文章

  • 堆总结(C语言)
    堆总结(C语言)二叉树的顺序结构及实现堆是什么堆的分类堆的实现堆的向下调整堆的向上调整堆的应用堆排序TOP-K问题思路:堆是什么堆总是一棵完全二叉树,堆是用来存完全二叉树的,如果存普通的二叉树就会浪费空间。堆(一种二叉树)使用顺序结构的数组来存储。堆不是简单的......
  • C/C++数字与字符串互相转换
    前言:在C/C++程序中,会需要把数字与字符串做出互相转换的操作,用于实现程序想要的效果。下面将介绍多种方法实现数字与字符串互相转换。字符串转为数字一、利用ASCII我们知道每个字符都有一个ASCII码,利用这一点可以将字符-'0'转为数字。在字母大小写转换时也可以利用这个性质......
  • 【配送路径规划】遗传算法求解带时间窗的电动汽车配送路径规划(目标函数:最小成本;约束条
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信或扫描文章底部QQ二维码。......
  • 【时时三省】(C语言基础)操作符3
    山不在高,有仙则名。水不在深,有龙则灵。             ----CSDN时时三省&取地址操作符示例: 每个内存单元都有自己的编号编号就成为内存单元的地址&a就是找出a的地址后面可以加一个int*pa=&a是可以用来存放地址pa是用来存放地址的-pa就是一......
  • 初识c语言
    什么是c语言c语言是一门计算机编程语言,可广泛用于底层开发。c语言是一种能以简易方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。第一个c语言程序入门第一个c语言代码如下:那么其运行的结果就是打印helloworld,运行结果如下:......
  • 【C语言(谭浩强)】程序设计与 C 语言
    博客主页:小蜗系列专栏:C语言(谭浩强)版关注博主,后期持续更新系列文章如果有错误请大家批评指出,我会及时修改感谢大家点赞......
  • C语言----结构体
    结构体结构体的含义自定义的数据类型它是由很多的数据组合成的一个整体,结构型数据其中的每一个数据,都是结构体的成员书写的位置:函数的里面:局部位置,只能再本函数中使用函数的外面:全局位置,在所有的函数中都可以使用#include<stdio.h>#include<string.h>structm......
  • Python 潮流周刊#64:Python 的函数调用还很慢么?(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。分享了11篇文章,13个开源项目,1则音视频,全文2000字。以下是本期摘要:......
  • Java中字符串的常量池
    计算机存储中存在一个堆区域,堆区域中存在一个常量池,当申请了字符串变量后,会将值放入常量池中,下次申请新的变量时,会优先从常量池中查找,如果常量池中已经存在,则变量会直接指向常量池中的值,从而节省空间(jdk1.8之后的字符串常量池存在于堆中) Stringx1="aaa";//在常量池......
  • C语言指针变量详解(函数指针,函数指针数组,转移表)
    指针变量 1.字符指针变量在指针的类型中我们知道有⼀种指针类型为字符指针char*;⼀般使⽤:intmain(){charch='w';char*pc=&ch;*pc='w';return0;}还有⼀种使⽤⽅式如下:intmain(){const......