> 文档中心 > c语言字符串函数超详解

c语言字符串函数超详解

文章目录

  • 一、字符串函数介绍
  • 二、函数介绍
    • 2.1 strlen
    • 2.2 长度不受限的字符串函数
      • 2.2.1 strcpy
      • 2.2.2 strcat
      • 2.2.3 strcmp
    • 2.3 长度受限的字符串函数
      • 2.3.1 strncpy
      • 2.3.2 strncat
      • 2.3.3 strncmp
    • 2.4字符串查找函数
      • 2.4.1 strstr
      • 2.4.2 strtok
    • 2.5 错误报告函数strerror
    • 2.6各种字符分类函数
  • 三、库函数模拟实现
    • 3.1 模拟实现strlen
    • 3.2 模拟实现strcpy
    • 3.3 模拟实现strcmp
    • 3.4 模拟实现strcat
    • 3.5 模拟实现strstr

一、字符串函数介绍

首先介绍一下字符串操作函数大概都有哪些:
求字符串长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍(对要操作的字节数给出了限制)
strncpy
strncat
strncmp
字符串查找
strstr
strtok
错误信息报告
strerror

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者 字符数组中。
字符串常量适用于那些对它不做修改的字符串函数.要认真看噢,进入正题

二、函数介绍

2.1 strlen

计算字符串长度

//格式size_t strlen (const char* str)

从地址位开始往后找直到’\0’处停止(所以我们在使用时,目标字符串内最好得有’\0’,否则得到的就是随机值),且’\0’不会计数

注意:

1.参数类型要用const修饰,加个const防止从strlen函数内部修改目标字符串内容(下面也同理)
2.strlen函数的返回值是size_t类型的无符号整型数,所以当直接使用其返回值进行计算时,由于内存对无符号类型数的读与取规则,可能会出错

2.2 长度不受限的字符串函数

2.2.1 strcpy

拷贝字符串

//格式char* strcpy(char* dest,const char* src)

注意:

1.由于拷贝函数是以源字符串的’\0’来截止拷贝操作的,所以要确保源字符串中有’\0’,否则将会传入很多随机值甚至报错(’\0’也是会被存进目标字符串中去的)
2.目标字符串空间必须足够大(拷贝时是不会考虑空间是否够大的)
3.目标必须可变(因为是将拷贝内容放进去,所以肯定得为可修改的)
4.这里将返回类型设置为了char * 而不是void ,使其有了函数的链式访问属性,可直接将返回值作为其他函数的参数进行使用(下面同理)
ex:
printf("%s\n",strcpy(s1,s2));

2.2.2 strcat

追加字符串
将源字符串接到字符串后面

//格式char* strcat(char* dest,const char* src)

注意:

1.源字符串中也要有’\0’,否则传进去随机值且可能会导致越界报错
2.源字符串接到目标字符串后面时会从‘\0’处开始接

2.2.3 strcmp

比较字符串函数
从第一位开始比较同位置的字符ascii码值大小;如果前者大于后者则返回大于0的整型值,后者大于前者返回小于0的整型值,两者相等返回0

//格式int strcmp(const char* dest,const char* drc)

2.3 长度受限的字符串函数

区别就是多传入个限制访问的字节数的参数而已,但还是有一些注意事项,下面分别简单说明一下

2.3.1 strncpy

//格式char* strncpy(char* dest,const char* src,size_t num)

注意:

当源字符串小于需要传入的字节个数时,会自动将’\0’补位拷贝进去

2.3.2 strncat

//格式char* strncat(char* dest,char* src,size_t num)

注意:

1.当需传入的字节数<源字符串大小时,会主动在目标字符串后一位补上’\0’
2.反之,则会在追加完字符串后再追加个’\0’然后停止追加
总之,就是都会增加个’\0’使该操作比较安全

2.3.3 strncmp

就是限制比较的字符个数

int strncmp(const char* dest,const char* rc,size_t num)

2.4字符串查找函数

2.4.1 strstr

查找子字符串函数
在目标字符串中寻找是否有源字符串,找到的话返回目标字符串中开始相等的地址,否则返回NULL指针

//格式char* strstr(const char* dest,const char* src)

注意:

1.需查找的字符串内容不能为空,无法在字符串中寻找空值

2.4.2 strtok

字符串分隔函数

char*strtok(char* dest,const char* sep)

第二个参数是一个自己定义的分隔符的字符串集合(只有写在sep里面的才会被当作是分隔符分开),返回值为返回标记的指针(标记就是被分隔开的子字符串)

注意:

1.当返回第一个标记时(即此子字符串在目标字符串中是一号位置),第一个参数必须为有效地址;且此函数内部会将第一个地址参数保存(可能用了static函数转换成静态变量进行储存)
2.当需要返回的不是第一个标记时,第一个参数为NULL(此时函数会在上次保存的地址中从同一个字符串中开始寻找下一个标记)
3.strtok找到一个标记后会将其用’\0’结尾,并返回其地址
4.strtok函数对字符串分隔操作会改变字符串内容,所以我们通常都是拷贝一份临时变量防止目标字符串被改变。

2.5 错误报告函数strerror

将错误码翻译成错误信息

//格式char* strerror(int errnum)

传入的参数为错误码,返回值为错误信息的字符串常量首元素地址((char*)因为错误信息是作为字符串常量保存在c语言中可以直接用其指针打印出来的)

这个函数相信大家一听多少有点懵b,错误码是什么?又该怎么调用传参呢?接下来就给大家简单讲一些知识

当库函数使用的时候,发生错误会把errno这个全局的错误变量设置为本次执行库函数产生的错误码,errno是c语言提供的一个全局变量,可以直接使用,放在文件中的
所以在调用库函数发生错误时可以使用strerror函数来查询错误原因(把errno直接传参就行了,但要记得声明头文件)

2.6各种字符分类函数

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

三、库函数模拟实现

3.1 模拟实现strlen

如下:

1//计数器方式int my_strlen(const char * str){ int count = 0; while(*str) { count++; str++; } return count;}
2//不创建临时变量的方法,递归实现int my_strlen(const char * str){ if(*str == '\0') return 0; else return 1+my_strlen(str+1);}
3//指针-指针的方式,指针相减得到的是他们中间的元素个数int my_strlen(char *s){char *p = s;while(*p != ‘\0)p++;return p-s;}

3.2 模拟实现strcpy

char *my_strcpy(char *dest, const char*src){  char *ret = dest; assert(dest&&src);//用assert函数来判断传入的指针是否为空,如果括号内表达式结果为假会直接报错,并显示错误所在文件、行数(要引用头文件),自己以后模拟实现也可以使用此函数判断指针有效性 while((*dest++ = *src++)) { ; } return ret;}

3.3 模拟实现strcmp

int my_strcmp (const char * src, const char * dst){ int ret = 0 ; assert(src != NULL);   assert(dest != NULL); while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)  ++src, ++dst; if ( ret < 0 )  ret = -1 ; else if ( ret > 0 )  ret = 1 ; return( ret );}

3.4 模拟实现strcat

char *my_strcat(char *dest, const char*src){ char *ret = dest; assert(dest&&src);  while(*dest) { dest++; } while((*dest++ = *src++)) { ; } return ret;}

3.5 模拟实现strstr

char *  strstr (const char * str1, const char * str2){ char *cp = (char *) str1; char *s1, *s2; if ( !*str2 )     return((char *)str1); while (*cp){  s1 = cp;  s2 = (char *) str2;  while ( *s1 && *s2 && !(*s1-*s2) )   s1++, s2++;  if (!*s2)   return(cp);  cp++;} return(NULL);  //注:strstr函数的实现还可以用KMP算法更精简的实现,具体内容小伙伴们可以自己去查查,由于篇幅问题这里就不多赘述了,或者俺看看啥时候有时间再补一篇哈      

好拉,今天的内容就到这啦,好久没更了有点手生了,大家见谅哈。若发现有误,欢迎评论区指正留言!