文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-09-15 05:14

关注

目录

一、函数介绍及其模拟实现

1.strlen

2.strcpy

3.strcat

4.strcmp 

5.strncpy

6.strncat

 7.strncmp

8.strstr

 9.strtok

10.strerror 

 11.其他字符串函数

二、内存函数 

1.memcpy

 2.memove

3.memcmp


前言

在平时我们处理一些数据时,尤其是字符串,我们经常会用到库函数中的strlen、strcmp等,C语言本身是没有字符串类型的,字符串通常放在常量字符串和字符数组中。

一、函数介绍及其模拟实现

1.strlen

(1)函数头部

size_t strlen( const char *string );

(2)注意事项

  • 字符串以 '\0'作为结束标志,strlen函数返回的是在字符串'\0'前面出现的字符的个数(不含\0)
  • 参数指向的字符串必须要以\0结束
  • 函数的返回值是类型是 size_t 这是无符号整型(易错)

+

(3)strlen的使用 

#include#includeint main(){char* str = "abcef";int len = strlen(str);//获取字符串的长度printf("%d",len);return 0;}

(4)strlen的模拟实现

//普通实现#includeint my_strlen(char *str) {int count = 0;while (*str++) count++;return count;}int main(){char* str = "abcdef";int len = my_strlen(str);printf("%d",len);return 0;}

//链式访问实现

#includeint my_strlen(char *str) {int count = 0;while (*str++) count++;return count;}int main(){char* str = "abcdef";printf("%d",my_strlen(str));//链式访问return 0;}

//函数递归实现

#includeint my_strlen(char* str){if (*str == '\0')return 0;elsereturn (1 + my_strlen(str + 1));}int main() {char* str = "abcdef";int len = my_strlen(str);printf("%d",len);return 0;}

//指针-指针实现

//指针- 指针#includeint my_strlen(char*str){char* end = str;while (*end)end++;return end - str;}int main() {char* str = "abcdef";int len = my_strlen(str);printf("%d",len);return 0;}

2.strcpy

(1)函数头部

char *strcpy( char *strDestination, const char *strSource ); 

(2)注意事项

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

 (3)strcpy的使用

#include#includeint main() {char str1[20] = {0};char* str2 = "abcdef";strcpy(str1,str2);printf("%s",str1);return 0;}
#include#includechar* my_strcpy(char* str1, const char* str2){assert(str1&&str2);//断言避免指针为空char* ret = str1;while (*str1++ = *str2++);return ret;}int main(){char str1[20] = { 0 };char* str2 = "abcdef";printf("%s", my_strcpy(str1, str2));return 0;}

3.strcat

(1)函数头部

char *strcat( char *strDestination, const char *strSource ); 

 (2)注意事项

  • 源字符必须以‘\0’结束
  • 目标空间必须有足够大能容纳下源字符串
  • 目标空间必须可以修改
  • strcat不能自己给自己追加

(3)strcat的使用

//strcat的使用#include#includeint main() {char str1[20] = "abcdef";char* str2 = "112233";strcat(str1,str2);printf("%s",str1);return 0;}


(4)strcat的模拟实现

#include#includechar* my_strcat(char*dest,const char*src) {char* ret = dest;while (*dest)dest++;while (*dest++ = *src++);return ret;}int main(){char str1[20] = "abcdef";char* str2 = "112233";my_strcat(str1, str2);printf("%s", str1);return 0;}

4.strcmp 

(1)函数头部

int strcmp( const char *string1, const char *string2 );

(2)注意事项

  • 根据标准规定
  • 第一个字符串 大于 第二个字符串,返回大于0的数字
  • 第一个字符串 等于 第二个字符串 ,返回0
  • 第一个字符串 小于 第二个字符串,返回小于0的数字 

(3)strcmp的使用 

#include#includeint main() {char* str1 = "abcdef";char* str2 = "aaaaaa";int ret = strcmp(str1,str2);//可以知道 str1>str2printf("%d",ret);//编译器返回一个大于0的数字return 0;}

(4)strcmp的模拟实现

#include#includeint  my_strcmp(const char*str1,const char*str2){assert(str1&&str2);while (*str1 == *str2) {if (*str1 == '\0')return 0;str1++;str2++;}return (*str1 - *str2);}int main(){char* str1 = "abcdef";char* str2 = "aaaaaa";int ret = my_strcmp(str1, str2);printf("%d", ret);return 0;}

我们发现上述字符串函数 的字符串长度不受到限制

接下来介绍几个长度受到限制的字符串函数


5.strncpy

(1)函数头部

char *strncpy( char *strDest, const char *strSource, size_t count );

(2)注意事项

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

(3)strncpy的使用

#include#includeint main() {char str1[20] = "aa";char str2[] = "bbb";strncpy(str1,str2,5);printf("%s",str1);return 0;}

接下来我们一下调试的内容

6.strncat

(1)函数头部

char *strncat( char *strDest, const char *strSource, size_t count );

(2)注意事项

  • 当源字符串小于count,并不会一直追加,而是追加完字符串的时候再加上‘\0’,目标是完成源字符串内容
  • 当等于count,会再追加一个上‘\0’
  • 没有额外追加

(3)strncat的使用

//strncat的使用#include#includeint main() {char str1[20] = "aaa";char* str2 = "bbc";strncat(str1,str2,3);printf("%s",str1);return 0;}

 7.strncmp

(1)函数头部

int strncmp( const char *string1, const char *string2, size_t count );

(2)注意事项

  • 比较到出现另一个字符不一样,或者一个字符串结束,或者count个字符全部比较完

< 0   不匹配的第一个字符在 str1 中的值低于 str2 中的值

0   两个字符串的内容相等 

>0  第一个不匹配的字符在str1中的值比在str2中的值大

(3) strncmp的使用

//strncmp的使用#include#includeint main() {char* str1 = "aaab";char* str2 = "abba";int len = strncmp(str1,str2,2);//比较前两个字符printf("%d",len);return 0;}


8.strstr

(1)函数头部

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

(2)注意事项

在str1中找  str2在(str1)第一次出现的位置

(3)strstr的使用
 

#include#includeint main() {char* str1 = "abcxaxad";char* str2 = "xax";char* ret = strstr(str1,str2);printf("%s",ret);return 0;}

(4)strstr模拟实现

//strstr的模拟实现#include#includechar* my_strstr(const char* str1,const char* str2) {assert(str1&&str2);char* cp = str1;char* p1 = str1;char* p2 = str2;while (cp) {p1 = cp;//从cp指向的字符开始p2 = str2;//从子串的首字符开始while (*p1 == *p2 && *p1 && *p2) {p1++;p2++;}if (*p2 == '\0')return cp;cp++;}return NULL;}int main() {char* str1 = "abcxaxad";char* str2 = "xax";char* ret = my_strstr(str1,str2);printf("%s",ret);return 0;}

图解:

起始情况

找到的时候

 

 9.strtok

(1)函数头部

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

(2)注意事项

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

(3)strtok的使用 ( 把字符串根据 分隔符  分隔开来)

#include#includeint main() {char* p = "aabbcc@112233.abc";const char* sep = "@.";char arr[30];char* str = NULL;strcpy(arr,p);//临时拷贝字符串for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))printf("%s\n",str);return 0;}

10.strerror 

返回错误码,所对应的错误信息(这里是程序运行时的错误)

在介绍其他知识:库函数在执行时,发生了错误,会将一个错误码存到errno这个变量中(全局变量)

(1)函数头部

char * strerror( int errnum );

(2)strerror的使用

#include#include#includeint main() {int i = 0;for (i = 0; i < 10;i++){printf("%d is %s\n",i,strerror(i));//打印错误码 0到9的错误信息}}


 11.其他字符串函数

字符分类函数
iscntr任何控制字符
isspace

空白字符: 空格 ' ',换页 ‘\f,换行 '\n',回车 '\r' ,制表符 ‘\t’,垂直制表符 ‘\v’

isdigit十进制数字 0 - 9
isxdigit十六进制数字 0 - 9 ,a - f
islower小写字母 a- z
isupper大写字母 A - Z
isalpha字母 a - z , A - Z
isalnum字母或者数字 a - z , A - Z,0 - 9
ispunct标点符号,任何不属于字母和数字的图形字符
isgragh任何图形字符
isprint可以打印任何字符

根据上述字符函数,【例如】islower(a) 如果圆括里面的是小写字母,该函数就返回真。

二、内存函数 

1.memcpy

(1)函数头部 

void *memcpy( void *dest, const void *src, size_t count );

(2)注意事项

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置
  • 这个函数在遇到 '\0' 的时候并不会停下来
  • 用来处理不重叠的内存拷贝,如果source和destination有任何的重叠,复制的结果都是未定义的
  • size_t  count 是 字节的个数

(3)memcp的使用

#include#includeint main() {int arr1[] = {1,2,3,4,5};int arr2[20] = {0};//将arr1中的内容拷贝到arr2中memcpy(arr2,arr1,20);int i = 0;for (i = 0; i < 20;i++){printf("%d ",arr2[i]);}return 0;}

 (4)memcpy的模拟使用

//memcpy的模拟实现#include#includevoid* my_memcpy(void* dest, const void *src ,size_t count) {assert(dest && src);void* ret = dest;while (count--)//count表示的是字节的个数{//因为char类型是占一个字节*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return dest;}int main(){int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = {0};my_memcpy(arr2,arr1,40);int i = 0;for (i = 0; i < 20;i++){printf("%d ",arr2[i]);}return 0;}

 2.memove

(1)函数头部

void *memmove( void *dest, const void *src, size_t count );

(2)注意事项

  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
  • 如果源空间和目标空间出现重叠,就是可以使用memmove进行处理​​​​​​
  • 用重叠的内存拷贝

(3)memmove的使用

#include#includeint main(){//这里我们给str自己拷贝一个123char str[] = "web online 123";memmove(str, str + 11,3);//可以用于重叠内存拷贝printf("%s",str);return 0;}

 

  (4)memmove的模拟实现

//memmove的模拟实现#include#includevoid* my_memmove(void* dest,const void* src,size_t num) {assert(dest&&src);void* ret = dest;//当地址src 小于 dest的时候if (dest < src) {//这里我们src从前到后移动//前->后while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else {while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;}int main(){int arr1[] = {1,2,3,4,5,6,7,8,9,10};my_memmove(arr1, arr1 + 2,12);//前->后//my_memmove(arr1+5,arr1+2,12);//后->前int i = 0;for (i = 0; i < 10;i++){printf("%d ",arr1[i]);}return 0;}

前->后 

后->前

 

情况1

情况2

3.memcmp

(1)函数头部

int memcmp( const void *buf1, const void *buf2, size_t count );

(2)注意事项

  • 比较从buf1 和 buf2 指针开始的num个字节
  • The memcmp function compares the first count bytes of buf1 and buf2 and returns a value indicating their relationship.

  • 注意该函数的return value 

(3)memcmp的使用

//memcmp的使用#include#includeint main(){char buf1[] = "aabbcc2210";char buf2[] = "aabbcc2211";int n = 0;n = memcmp(buf1,buf2,sizeof(buf1));if (n > 0)printf("buf1大于buf2");else if (n < 0)printf("buf1小于buf2");elseprintf("buf1等于buf2");return 0;}

来源地址:https://blog.csdn.net/qq_72505850/article/details/132661899

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯