字符函数和字符串函数第一部分

本章内容:

一. 求字符串长度

    。     strlen

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

    。     strcpy

    。     strcat

    。     strcmp

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

   。      strncpy

   。      strncat

   。      strncmp

四.字符串查找

   。      strstr

   。      strtok

五.返回错误码

  。strerror

接下来开始正文讲解:

一. 求字符串长度

                                        1.strlen

size_t strlen(const char * str);

字符串以 ' \0 ' 作为结束标志,strlen函数返回的是在字符串中 ' \0 ' 前出现的字符个数(不包含 ' \0 ')。

参数指向的字符串必须要以' \0 '结束。

注意函数的返回值为size_t , 是无符号的。

头文件是:#include<string.h>

我们先用一个字符串数组举例:

 我们看到得出的结果是6,因为字符串abcdef里隐藏着' \0 ',实际上就是“abcdef\0”,所以当strlen从首字符a开始读,当读到'\0'时停止,计算出' \0 '之前的字符个数,所以是6。

_____________________________________________________________________________

那么我们用单个字符初始化数组,再用strlen计算数组长度看一下会是什么结果:

 解析:我们看到得到的结果是出人意料的23,这是因为数组中只开辟了六个空间来存放字符'a','b','c','d','e','f'的,内存中' f '的后面放着是什么是不知道的,而strlen函数的特点是从前向后一直找'\0',直到找到'\0'为止,这段代码的结果是23,说明在'\0'之前出现了23个非'\0'的字符,所以求出来的结果是23,23是个随机值。

_____________________________________________________________________________

那么这段代码想要求出正确的结果就需要在数组中最后一个字符后面加上'\0',代码如下:

这段代码如果指定数组的大小也可以输出正确的结果,请看代码:

我们看到当我们指定了数组的大小后也可以输出正确的结果,这是因为数组arr有10个空,但只用了'a','b','c','d','e','f'是6个字符进行初始化,剩下4个没有初始化的空间编译器会默认初始化为 0 ,0 就是'\0',所以会得到正确的答案。(下面放一张调试图)

——————————————————————————————————————————-

注意函数 strlen的返回值是size_t,是无符号的,所以会导致在计算的时候使用不当会出现bug,我们举个例子:

想必有的小伙伴看到这道题会觉得应该是<号,但答案为什么是>号,“abc”返回的是无符号3,“qwerty”返回的是无符号的6,“abc” - “qwerty” = -3,但由于函数 strlen的返回值无符号的数,所以得到的-3是一个无符号数,如果-3被理解为一个无符号数,将会是一个超级大的正数,所以这个非常大的正数一定是大于0的。

这种代码只要换个方法就可以得到正确结果,比如进行强制类型转换:

也可以把减号换成大于号:

———————————————————————————————————————————

模拟实现strlen函数:

1.以计数器的方法模拟实现 :

2.编写函数不允许创建临时变量,求字符串的长度

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

                                   2.strcpy

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

头文件是:#include<string.h>

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

下面展示一下strcpy的基本用法:

—————————————————————————————————————— 

strcpy函数会将源字符串中的'\0' 拷贝到目标空间,如果原字符串中没有'\0',则会导致程序崩溃,例如:

如果想改进的话有三种方法,看代码(注意看注释):

那么如何证明strcpy函数会将源字符串中的'\0' 拷贝到目标空间 ?我们使用调试来证明:

 ——————————————————————————————————————————

在使用strcpy函数时目标空间必须可变。我们使用一个常量字符串来举例:

我们可以看到目标空间是常量字符串,是不可变的,所以会报错。

———————————————————————————————————————————

模拟实现strcpy

方法1:

方法二(更加简洁):

-------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                               

                          3.strcat(字符串追加

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

头文件是:#include<string.h>

  • 源字符串必须以' \0 '结束。
  • 目标空间必须足够大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 字符串自己给自己追加,如何?

我们先举例说明这个函数的用法:

注意strcat函数在使用时源字符串中必须有'\0',目标字符串中也必须有'\0',因为源字符串在追加的时候需要找到目标字符串中'\0'的位置,然后从目标字符串中的'\0'开始进行向后追加,追加时,以源字符串某位的'\0'作为结束标志。我们使用调试给大家解释:

———————————————————————————————————————————

模拟实现strcat

———————————————————————————————————————————

如果字符串自己给自己追加,如何?会出现什么状况呢?

我们可以看到如果字符串自己给自己追加会导致程序奔溃。\0 会被覆盖,造成死循环。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                                           

                                      4.strcmp (字符串比较)

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

  • 标准规定:
  1.  第一个字符串大于第二个字符串,则返回大于0的数字
  2.  第一个字符串等于第二个字符串,则返回0
  3.  第一个字符串小于第二个字符串,则返回小于0的数字

 注意:strcmp函数比较的不是字符串的长度,而是比较字符串中对应位置上的字符的大小(ASCII码值),如果相同,就比较下一对,直到不同或者遇到 \0

下面是strcmp的使用方法:

——————————————————————————————————————————— 

模拟实现strcmp

 

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以上讲的strcpy、strcat、strcmp都是长度不受限制的字符串函数,使用不当的时候会有风险,比如目标字符串空间不够放源字符串的字符串就会出问题。

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

下面是长度受限制的字符串函数:

strncpy

strncat

strncmp

5.strncpy

char*strncpy(char* strDest, const char* strSource, size_t count);  //size_t count是要拷贝字符的个数

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

strncpy的使用方法:

——————————————————————————————————————————————————————

那么有同学会好奇,如果在源字符串arr2中只有3个字符的前提下,强行给目标字符串arr1拷贝5个字符,会发生什么状况?

我们用代码和调试验证一下:

我们可以看到确实操作了5个字符 (qwe\0\0),所以我们发现如果源文件中字符的个数只有3个,不够我想要追加的5个字符个数,如果强行追加的话arr2会强行追加够这5个空间,字符不够的地方拿'\0'来填充。 但是大家在实际开发中不要这样瞎搞,否则容易出bug。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6.strncat

char* strncat(char* destination, const char* source, size_t num);//size_t num是要追加字符的个数

strncat使用方法

  注意:在追加的时候arr1中必须有'\0',arr2找到arr1中的'\0'之后,在arr1的'\0'的位置上进行追加,将arr2中的5个字符(qwerty)追加到arr1字符串的后面,注意在这5个字符(qwerty)后会自动追加一个'\0'让它们形成一个字符串,我们来看调试:

那么有同学要问了,如果arr2字符串中只有3个字符的话,我们从arr2中强行追加5个字符给arr1会发生什么?让我们看调试结果:

我们可以看到,即使从只有三个字符的arr2字符串中强行追加5个字符给 arr1,结果依旧是只将arr2字符串中有限的三个追加过去,然后在末尾追加一个'\0'。但是这种用法不建议使用。

———————————————————————————————————————————————————————

strcat中我们知道字符串自己给自己追加会导致程序奔溃,但是在strncat中我们可以实现字符串自己给自己追加,下面我们看代码:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

7.strncmp

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

  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
  •  第一个字符串大于第二个字符串,则返回大于0的数字
  •  第一个字符串等于第二个字符串,则返回0
  •  第一个字符串小于第二个字符串,则返回小于0的数字

strncmp的使用方法:

 ——————————————————————————————————————————————————————

注意:两个字符串强行比较比较的其实是两个数组的地址:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

四.字符串查找

8.strstr

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

这个函数的功能是在一个字符串中找另外一个字符串,看一个字符串是不是另外一个字符串的子串。

strstr的使用方法:

___________________________________________________________________________________________________

模拟实现strstr

 

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

8.strtok

char* strtok(char* str,const char* sep);

头文件是:#include<string>

  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
  • strtok函数找到str中的下一个标记,并将其用'\0'结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
  • strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个目标
  • 如果字符串中不存在更多的标记,则返回NULL

下面我们用代码解释上面的这些论点(请认真阅读注释,为了更好地说明strtok函数的用法,注释写的稍微啰嗦和重复了些):

不过在实际的开发中很少这样分开写,我们了解strtok函数后可以这样写:

 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 五.返回错误码

9.strerroe(返回错误码所对应的信息

char* strerror(int errnum); /*只要给函数传入一个错误码,就可以把错误码所对应错误信息的字符                                                串 的起始地址返回*/

#include<string.h>

#include<erron.h> //必须包含的头文件

这个函数的使用方法:

 我们可以看到一个错误码对应一个错误信息,有同学会问这个函数就是这么用吗,其实不是的,有个全局变量叫errno,当我们通常调用库函数失败的时候可以用到,比如这样(注意看注释):

 

———————————————————————————————————————————

10.perror

void perror(const char* string); //参数传入的是字符串

除了strerror这个函数外还有一个函数叫 perror,可以将错误码对应的错误信息直接打印出来:

注意:打印结果中的malloc:Not enough space中的malloc是自定义的。

 —————————————————————————————————————————————————————————————————————————————————------—

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值