C语言常用字符串函数
创始人
2024-05-10 06:00:05
0

专栏:C语言
每日一句:别在乎别人的目光,自己只管一心走路。熬过去,你就能看到柳暗花明,熬过去,你就能看到雨后彩虹,熬过去,你就能看到动人风景。

字符串函数

  • 前言
  • 一、求字符串长度:strlen
    • 1.strlen的简单介绍
    • 2.strlen的模拟实现
      • 2.1利用指针-指针实现
      • 2.2利用递归实现
      • 2.3利用循环实现
  • 二、拷贝字符串strcpy和strncpy
    • 1.strcpy的介绍
      • 1.1strcpy的模拟实现
    • 2.strncpy的简单介绍
  • 三、连接字符串strcat和strncat
    • 1.strcat的简单介绍
      • 1.1strcat模拟实现
    • 2.strncat的简单介绍
  • 四、比较字符串strcmp和strncmp
    • 1.strcmp的简单介绍
      • 1.1strcmp的模拟实现
    • 2.strncmp的简单介绍
  • 五、查找字符穿strstr
    • 1.strstr的简单介绍
      • 1.1strstr的模拟实现
  • 六、错误信息strerror和perror
    • 1.strerror的简单介绍
    • 2.perror的简单介绍
  • 七、内存函数memcpy,memmove和memset
    • 1memcpy的简单介绍
      • 1.1memcpy的模拟实现
    • 2.memmove的简单介绍
      • 2.1memmove的模拟实现
    • 3.memset的简单介绍
  • 总结


前言

本文重点介绍处理字符和字符串库函数的使用和注意事项

在这里插入图片描述

文章中的函数介绍图片来源于cplusplus.com

一、求字符串长度:strlen

1.strlen的简单介绍

在这里插入图片描述
strlen函数的作用是求字符串长度

size_t strlen(const char *str);

字符串是已‘\0'作为结束标志,strlen函数返回的是在字符串中出现在'\0'之前的有效字符的个数。
参数str指向的字符串必须要以'\0'作为结束标志
注意函数的返回值为size_t,size_t是无符号的
在这里插入图片描述

2.strlen的模拟实现

在这里,给大家介绍三种实现方式

2.1利用指针-指针实现

前面介绍过,指针-指针得到的是元素之间的个数,利用这个原理,就能实现strlen

#include 
#include 
int my_strlen(const char* str)
{assert(str);const char* st = str;记录str的起始地址while (*++str);return str - st;
}
int main()
{char str[] = "abcdef";int len = my_strlen(str);printf("%d\n", len);return 0;
}

在这里插入图片描述

2.2利用递归实现

如果*str不为'\0'就可以return 1 + my_strlen(++str)这样每次都可以+1,直到遇到字符串的结束标志'\0',结束递归。

#include 
#include 
int my_strlen(const char* str)
{assert(str);if (*str){return 1 + my_strlen(++str);}else{return 0;}
}int main()
{char str[] = "abcdef";int len = my_strlen(str);printf("%d\n", len);return 0;
}

在这里插入图片描述

2.3利用循环实现

利用循环实现很简单,循环只要不遇到'\0',就继续循环。

#include 
#include 
int my_strlen(const char* str)
{assert(str);int cnt = 0;while (*str){cnt++;str++;}return cnt;
}int main()
{char str[] = "abcdef";int len = my_strlen(str);printf("%d\n", len);return 0;
}

在这里插入图片描述

二、拷贝字符串strcpy和strncpy

1.strcpy的介绍

在这里插入图片描述

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

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

1.1strcpy的模拟实现

#include 
#include char* my_strcpy(char* str1, const char* arr2)
{assert(str1 && arr2);char* ret = str1;while (*str1++ = *arr2++);return ret;
}int main()
{char str1[20] = "";const char arr2[] = "h h x x";my_strcpy(str1, arr2);printf("%s", str1);return 0;
}

在这里插入图片描述

注:strcpy的返回值是目标字符串的起始地址

2.strncpy的简单介绍

在这里插入图片描述

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

拷贝num个字符从源字符串到目标字符串中
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标字符串的后面追加0,直到够num个为止

在这里插入图片描述

三、连接字符串strcat和strncat

1.strcat的简单介绍

在这里插入图片描述

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

源字符串必须以'\0'为结束标志
目标空间必须足够大,以确保能够容纳源字符串的内容
目标空间必须可变

1.1strcat模拟实现

要模拟实现strcat,需要先找到目标字符串的尾,也就是’\0’的位置,然后让源字符串的内容连接在目标字符串后面即可

#include 
#include char* my_strcat(char* arr, const char* str)
{assert(arr && str);char* ret = arr;while (*++arr);while (*arr++ = *str++);return ret;
}int main()
{char arr[20] = "hao hao";const char str[10] = " xue xi";my_strcat(arr, str);printf("%s", arr);return 0;
}

在这里插入图片描述

2.strncat的简单介绍

在这里插入图片描述

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

如果源字符串的长度小于 num,则仅复制源字符串的结束标志之前的内容。

在这里插入图片描述

四、比较字符串strcmp和strncmp

1.strcmp的简单介绍

在这里插入图片描述

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

这个strcmp是比较字符串的函数,但它并不是一串一串的比较,而是一个字符一个字符的比较。
如果str1 > str2 则返回 1
如果str1 = str2 则返回 0
如果srt1 < str2 则返回 -1

1.1strcmp的模拟实现

#include 
#include 
#include 
int my_strcmp(const char* arr, const char* str)
{assert(arr && str);while (*arr == *str){if (!*arr){return 0;}arr++;str++;}if (*arr > *str){return 1;}else{return -1;}
}int main()
{char arr[20] = "ba";const char str[10] = "bd";int cmp = my_strcmp(arr, str);printf("%d\n%d", cmp, strcmp(arr, str));return 0;
}

在这里插入图片描述

2.strncmp的简单介绍

在这里插入图片描述

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

在这里,num是要比较的字符个数。

在这里插入图片描述

五、查找字符穿strstr

1.strstr的简单介绍

在这里插入图片描述

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

str2 中指定的整个字符序列在 str1 中首次出现的位置,如果序列在 str1 中不存在,则返回null 指针。

1.1strstr的模拟实现

#include int n, m;int ne[20];char* my_strstr(char* str, char* ch)
{for (int i = 2, j = 0; i <= n; i++){while (j && str[i] != str[j + 1]){j = ne[j];}if (str[i] == str[j + 1]){j++;}ne[i] = j;}for (int i = 1, j = 0; i <= m; i++){while (j && ch[i] != str[j + 1]){j = ne[j];}if (ch[i] == str[j + 1]){j++;}if (j == n){return ch + i + 1 - n;break;}}
}int main()
{char str[20], ch[20];scanf("%d%s%d%s", &n, (str + 1), &m, (ch + 1));printf("%s", my_strstr(str, ch));return 0;
}

在这里插入图片描述

六、错误信息strerror和perror

1.strerror的简单介绍

在这里插入图片描述

char * strerror ( int errnum );

返回错误码所对应的错误信息。

#include 
#include int main()
{printf("%s\n", strerror(0));printf("%s\n", strerror(1));printf("%s\n", strerror(2));printf("%s\n", strerror(3));printf("%s\n", strerror(4));printf("%s\n", strerror(5));return 0;
}

在这里插入图片描述
这就是一些错误信息。

2.perror的简单介绍

在这里插入图片描述

void perror ( const char * str );

打印报错信息

#include 
#include int main()
{FILE* fp = fopen("Haifan.txt", "r");//这里并没有该文件if (fp == NULL){perror("fp");}/*fclose(fp);fp = NULL;*/return 0;
}

在这里插入图片描述

七、内存函数memcpy,memmove和memset

1memcpy的简单介绍

在这里插入图片描述

void * memcpy ( void * destination, const void * source, size_t num );

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

1.1memcpy的模拟实现

#include 
#include 
#include 
void* my_memcpy(void* arr1, const void* arr2, size_t num)
{assert(arr1 && arr2);void* ret = arr1;while (num--){*((char*)arr1) = *((char*)arr2);arr1 = (char*)arr1 + 1;arr2 = (char*)arr2 + 1;}return ret;
}int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[5] = { 0 };my_memcpy(arr1, arr2, 8);return 0;}

在这里插入图片描述

2.memmove的简单介绍

在这里插入图片描述

void * memmove ( void * destination, const void * source, size_t num );

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。

2.1memmove的模拟实现

#include 
#include 
#include void* my_memmove(void* arr1, const void* arr2, size_t num)
{assert(arr1 && arr2);void* ret = arr1;if (arr1 < arr2){while (num--){*((char*)arr1) = *((char*)arr2);arr1 = (char*)arr1 + 1;arr2 = (char*)arr2 + 1;}}else{while (num--){*((char*)arr1 + num) = *((char*)arr2 + num);}}return ret;
}int main()
{int arr1[] = { 1,2,3,4,5 };my_memmove(arr1+1, arr1, 16);int arr2[] = { 1,2,3,4,5 };memmove(arr2 + 1, arr2, 16);return 0;
}

在这里插入图片描述

3.memset的简单介绍

在这里插入图片描述

void * memset ( void * ptr, int value, size_t num );

这个函数是对ptr按字节把ptr每一个字节初始化成value,一共是num个字节

#include 
#include int main()
{int arr[5] = { 0 };memset(arr, 0x3f, sizeof(arr));return 0;
}

在这里插入图片描述
在这里插入图片描述
这样,就能把arr的每个字节变成了0x3f

总结

以上是对常用字符串函数的总结,希望对大家有所帮助。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...