一.字符串具体有哪些

求字符串的长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍
strncpy
strncat
strncmp
字符串查找
strstr
strtok
错误信息报告
strerror

字符操作

内存操作函数
memcpy
memmove
memset
memcmp

二.具体的函数的介绍

1.strlen

size_t strlen ( const char * str );
/*
具体语法
字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包
含 '\0' )。
size_t strlen ( const char * str );
参数指向的字符串必须要以 '\0' 结束。
注意函数的返回值为size_t,是无符号的( 易错 )
*/

具体的使用

int main() {char arr[] = "abc\0";printf("%d\n", strlen(arr));char brr[] = { 'a','b','c','\0'};printf("%d\n",strlen(brr));return 0;

模拟实现strlen

size_t my_strlen(const char* str)
{assert(str);const char* start = str;const char* end = str;while (*end != '\0'){end++;}return end - start;
}int main()
{char arr[] = "abcdef";int len = my_strlen(arr);printf("%d\n", len);return 0;
}

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

拷贝字符串
strcpy
剪切字符串
strcat
比较字符串
strcmp
下面让我一个一个去看这些方法的用法

  • strcpy
char* strcpy(char * destination, const char * source );
/*
Copies the C string pointed by source into the array pointed by destination, including the
terminating null character (and stopping at that point).
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。*/

具体用法

int main()
{char arr[10] = "xxxxxxxxx";const char* p = "abcdef";char arr2[] = { 'b', 'i', 't','\0'};strcpy(arr, p);strcpy(arr, arr2);printf("%s\n", arr);return 0;
}

这里我们监视变量就可以看出它是如何复制字符串的

模拟实现strcpy
这里模拟实现拷贝字符串的方法,是用指针相对调用而形成的

char* my_strcopy(char* dest,const char*src) {assert(dest);assert(src);char* ret = dest;while (*dest++ = *src++){;}return dest;
}
int main() {char arr1[20] = "abc";char arr2[] = "helloworld";my_strcopy(arr1, arr2);printf("%s\n", arr1);return 0;
}

strcat函数的具体说明
这个函数以"\0"为标识的 进行追加的。

char * strcat ( char * destination, const char * source );
源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

具体的用法

追加字符串
int main() {char arr1[20] = "hello";char arr2[20] = "world";strcat(arr1,arr2);printf("%s\n",arr1);return 0;

我们看图说话,目前看来可以说是以“\0”为追加的。

strcat的模拟实现

char* my_strcat(char*dest ,const char*src) {//1.找目标函数的\0char* cur = dest;while (*cur!='\0') {cur++;}//2..拷贝源头数据到\0之后while (*cur++ = *src++) {;  }
}
int main() {char arr1[20] = "hello \0xxxxxxxxxx";char arr2[] = "world";my_strcat(arr1,arr2);printf("%s\n",arr1);return 0;
}

strcmp 字符串的比较
这个函数就十分的简单,我就简单的说明一下,这个字符串比较函数,实际上就是一个一个字节字节的比对。
具体的使用

/*
实际上是一个字节一个字节的比较
实际上比较对应位置上字符的大小,而并非长度
*/
int main() {char arr1[] = "abcdef";char arr2[] = "abq";int ret = strcmp(arr1,arr2);printf("%d\n",ret);return 0;}

具体的函数实现

int my_strcmp(const char* s1, const char* s2) {assert(s1 && s2);while (*s1 == *s2) {if (*s1=='\0') {return 0;}s1++;s2++;}if (*s1 > *s2) {return 1;}else {return -1;}
}
//字符串比较函数的实现
int main() {char arr1[] = "abc";char arr2[] = "abq";int ret=my_strcmp(arr1,arr2);if (ret > 0) {printf("arr1>arr2");}else if (ret < 0) {printf("arr1<arr2");}else {printf("arr1==arr2");}return 0;
}

这三组函数,长度受限制,顾名思义,我们做操作的时候,可以指定数量
strncpy

char * strncpy ( char * 目标, const char * 源, size_t num );
从字符串中复制字符
将source的前num个字符 复制到destination。如果在复制num个字符之前找到源C 字符串的结尾(由空字符表示) ,则用零填充目标,直到总共写入了num个字符。如果source长于num ,则不会在目标 末尾隐式附加空字符。因此,在这种情况下,目的地不应被视为以空结尾的 C 字符串(这样读取它会溢出)。目的地和
int main()
{char arr1[20] = "abcdefghi";char arr2[] = "xxxx";strncpy(arr1, arr2, 8);printf("%s\n", arr1);return 0;
}

strncat


int main()
{char arr1[20] = "abcdef\0qqqqqq";char arr2[] = "xyz";strncat(arr1, arr2, 2);printf("%s\n", arr1);return 0;
}

strncmp

int main()
{int ret = strncmp("abcdef", "abc", 4);printf("%d\n", ret);return 0;
}

3.字符串查找

strstr

char * strstr ( const char *str1, const char * str2);
定位子串
返回指向 str1 中第一次出现str2的指针,如果str2不是 str1 的一部分,则返回空指针。 匹配过程不包括终止的空字符,但它会停在那里。

这里大概的意思是,记录字串第一次出现的位置
具体用法

int main() {char arr1[] = "abcdef";char arr2[] = "bcd";char* p = strstr(arr1, arr2);if (p == NULL) {printf("不存在");}else{printf("%s\n",p);}
}

strstr 模拟实现
这个方法不好理解,我画个图大家理解一下

char* my_strstr(const char* str1, const char* str2)
{const char* s1 = str1;const char* s2 = str2;const char* p = str1;if (*str2 == '\0'){return str1;}while (*p){s1 = p;s2 = str2;while (*s1 != '\0' && *s2 != '\0' && (*s1 == *s2)){s1++;s2++;}if (*s2 == '\0'){return (char*)p;//找到了}p++;}return NULL;//找不到子串
}
int main()
{char arr1[] = "abcdefabcdef";char arr2[] = "fab";char* p = my_strstr(arr1, arr2);if (p == NULL){printf("不存在\n");}else{printf("%s\n", p);}return 0;
}

3.内存操作函数
memcpy

 memcpy 的函数用法
int main() {int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int arr2[10] = { 0 };memcpy(arr2, arr, 20);float arr1[] = { 1.0f,2.0f,3.0f,4.0f };float arr2[] = { 0.0 };return 0;
}

具体模拟实现

// 如何自己实现memcpy
void* my_memcpy(void* dest,void* src,size_t num) {assert(dest);assert(src);void* ret = dest;while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;}
int main() {int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int arr2[10] = { 0 };my_memcpy(arr2, arr, 20);int i = 0;for (i = 0; i < 10; i++) {printf("%d",arr2[i]);}float arr3[] = { 1.0f,2.0f,3.0f,4.0f };float arr4[] = { 0.0 };my_memcpy(arr4, arr3, 20);return 0;
}

这里我们引入一个问题,如果我们自己拷贝自己的话
是否会成功吗?
试一试就知道了

int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };memcpy(arr1 + 2, arr1, 20);//memmove(arr1+2, arr1, 20);//int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//int arr2[10] = { 0 };//my_memcpy(arr2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}

运行截图

你看,我们这里,就出现了自己拷贝自己的问题,
简单来说,就是,我们正常拷贝的时候,会出现以下情况

所以我们拷贝数据有时候不能从前往后拷贝,有时候会覆盖,这样我们可以考虑从后向前拷贝,我把这样的情况分为以下三种情况

改进之后的代码,如下

void* my_memcpy(void* dest,void* src,size_t num) {assert(dest);assert(src);void* ret = dest;if (dest < 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 arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };my_memcpy(arr+2, arr, 20);int i = 0;for (i = 0; i < 10; i++) {printf("%d ",arr[i]);}return 0;
}

memmove

void * memmove ( void * dst, const void * src, size_t count) {void * ret = dst;if (dst <= src || (char *)dst >= ((char *)src + count)) {/** Non-Overlapping Buffers
比特就业课-专注IT大学生就业的精品课程 比特主页:https://m.cctalk.com/inst/s9yewhfr 比特就业课
本章完* copy from lower addresses to higher addresses*/while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst + 1;src = (char *)src + 1;}}else {/** Overlapping Buffers* copy from higher addresses to lower addresses*/dst = (char *)dst + count - 1;src = (char *)src + count - 1;while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst - 1;src = (char *)src - 1;}}return(ret);
}

memset

具体用法

int main() {int arr[] = { 1,2,3,4,5 };memset(arr, 0, 8);return 0;
}

memcmp

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

具体用法

memcmp的使用
int main() {int arr2[] = { 1,2,3,0,0 };int arr1[] = { 1,2,3,4,5 };int ret=memcmp(arr1, arr2,12);printf("%d\n",ret);return 0;}

模拟实现

void * memcpy ( void * dst, const void * src, size_t count) {void * ret = dst;assert(dst);assert(src);/** copy from lower addresses to higher addresses*/while (count--) {*(char *)dst = *(char *)src;dst = (char *)dst + 1;src = (char *)src + 1;}return(ret);
}

C语言字符串函数的详解相关推荐

  1. c语言 is函数,关于C语言回调函数的详解~

    原标题:关于C语言回调函数的详解~ 01 什么是回调函数? 回调函数,光听名字就比普通函数要高大上一些,那到底什么是回调函数呢?恕我读得书少,没有在那本书上看到关于回调函数的定义.我在百度上搜了一下, ...

  2. c语言while函数作用,详解C语言中的while语句

    什么是C语言的while语句?它的作用是什么呢?估计很多初学者对此都是一知半解.下面课课家笔者就为大家详细解释C语言中的while语句的含义和作用. 首先笔者先给大家介绍C语言中的共有的三大常用的程序 ...

  3. c语言fclose函数作用,详解C语言中freopen()函数和fclose()函数的用法

    C语言freopen()函数:打开文件函数,并获得文件句柄 头文件: #include 定义函数: FILE * freopen(const char * path,const char * mode ...

  4. js去掉前后空格的函数_MySQL 中常见的字符串函数应用详解

    在前面若干章节中,我们介绍了SQL的基础与高阶语法,接下来,我们将分四个章节,介绍MySQL中常见的函数应用,大致分为如下几个章节: MySQL 字符串函数 MySQL 数字函数 MySQL 日期函数 ...

  5. c语言复杂函数转换,详解C语言常用的一些转换工具函数.pdf

    详详解解C语语言言常常用用的的一一些些转转换换工工具具函函数数 1..字字符符串串转转十十六六进进制制 代码实现: void StrToHex(char *pbDest, char *pbSrc, i ...

  6. C语言字符串string.h详解

    本文已整合到C语言标准库深度解读 文章目录 查询函数 比较函数 复制和追加 本地函数 为了看上去规整简洁,令 #define cSTR const char *str #define vSTR con ...

  7. C语言main函数参数详解

    main函数参数 一共有三个: 1.int argc 整型变量 2.char *argv[] 字符指针的数组,通俗一点就是字符串数组,每个元素都是字符串 3.char *envp[] 字符串数组 这三 ...

  8. puts函数,C语言puts函数用法详解

    前面在输出字符串时都使用printf,通过"%s"输出字符串.其实还有更简单的方法,就是使用 puts() 函数.该函数的原型为: # include <stdio.h> ...

  9. C/C++字符串函数strtok()详解

    函数作用 找到与delimiter相同的地方,将其截断,并返回str 函数理解 第一个参数str是待切割字符串 第二个参数delimiter是分隔符字符串 返回值为char * ,一般默认返回str的 ...

最新文章

  1. 【数据平台】Centos下仅CPU安装TensorFlow
  2. ML之XGBoost:XGBoost算法模型(相关配图)的简介(XGBoost并行处理)、关键思路、代码实现(目标函数/评价函数)、安装、使用方法、案例应用之详细攻略
  3. opencv 眼睛识别 linux,用opencv测试人脸识别眨眼练习及问题
  4. Centos搭建FTP服务
  5. 还不会子网划分?看这篇文章还远远不够!
  6. 无人驾驶五 使用pure pursuit实现无人车轨迹追踪(python)
  7. Asp.Net Web API(四)
  8. Linux中断技术、门描述符、IDT(中断描述符表)、异常控制技术总结归类
  9. 2013=730 胆子要大,敢想敢做
  10. ADSL桥接模式和路由模式的区别(转)
  11. 安全跑路指南2013之乌云版
  12. Android app使用TextToSpeech实现文字转换语音
  13. 2021-08-26 工作记录--YDUI-带确认按钮的弹出框
  14. 第五课 大数据技术之Fink1.13的实战学习-状态编程和容错机制
  15. 使用Navicat连接Mycat的诡异事件
  16. 阳台柜也可以做出别样的效果!
  17. 数字的翻译(英文到中文)
  18. Azure认证 Administrator Associate(AZ-104) 考试指南,资料分享
  19. Python itchat模块报错:为了你的帐号安全,此微信号不能登录网页微信。你可以使用Windows微信或Mac微信在电脑端登录。
  20. Spine 导出视频 音效事件

热门文章

  1. 程序员这个职业赚钱吗?能赚多少钱?
  2. PS中各种滤镜效果的实现
  3. 2009年全球新装光伏发电系统将达到4GW
  4. 页面表格怎么添加序号
  5. spring5中文文档
  6. POWER BI中国主要城市交通健康榜
  7. html字体竖排旋转180度,css3+jq--小箭头旋转180度案例
  8. Java技术开发交流V群
  9. java stream取对象Long类型属性最大值
  10. Maven项目POM配置好后,下载jar包位置设置(本地仓库配置)