C语言中10个字符串函数详解

ops/2024/10/18 13:26:17/

目录

1.strlen

2.strcpy

3.strcat

4.strcmp

5.strncpy

6.strncat

7.strncmp

8.strstr

9.strtok

10.strerror

1.strlen

  • 基本结构:size_t strlen(const char *str);
  • 功能:用于计算字符串的长度;
  • 字符串已经 '0'作为结束标志,strlen函数返回的是在字符串中'\0’前面出现的字符个数;
  • 参数指向的字符串必须要以'0'结束;
  • 注意函数的返回值为size_t,是无符号的(易错);

(1)库函数用法

#include <string.h>
int main()
{char arr[] = "abc";char arr1[] = { 'a', 'b', 'c' };int len = strlen(arr);int len1 = strlen(arr);printf("%d\n", len);printf("%d\n", len1);  //随机值,arr1没得'\0'return 0;
}

(2)自定义函数 - 模拟实现strlen

可以分为三种写法:计数器版本、递归版本和指针减去指针版本。

//a.计算器版本
#include <assert.h>
int my_strlen(const char* str)   //str数组名表示数组第一个元素地址
{int count = 0;   //计数器assert(str != NULL);   //断言,确保str不是空指针while (*str != '\0'){count++;str++;}return count;
}//b.递归版本
int my_strlen(char* str)
{if (*str != '\0')return 1 + my_strlen(str + 1);elsereturn 0;
}//c.指针减去指针的版本
int my_strlen(char* str)
{char* start = str;while (*str != '\0'){str++;}return str - start;
}int main()
{char arr[] = "abc";int len = my_strlen(arr);printf("%d\n", len);return 0;
}

2.strcpy

  • 基本结构:char* strcpy(char *destination,const char *source );
  • 功能:用于字符串的复制;
  • 源字符串必须以'\0'结束;
  • 会将源字符串中的'0'拷贝到目标空间;
  • 目标空间必须足够大,以确保能存放源字符串;
  • 目标空间必须可变。

(1)库函数用法

int main()
{//a.正确用法char arr[20] = "#############";strcpy(arr, "hello");printf("%s\n", arr);//b.错位用法:源字符串中必须包括'\0'//char arr1[] = { 'a', 'b', 'c' };   //不行,拷贝的时候必须带'\0'//strcpy(arr, arr2);//c.错误用法:目标空间必须足够大,能放下源字符串//char arr[5] = "#####";//char *p = "hello word";//strcpy(arr, p);//d.错误用法:目标空间必须可变。//char* str = "###########";//char *p = "hello word";//strcpy(str, p);	return 0;
}

(2)模拟实现strcpy

#include <assert.h>char* my_strcpy(char* dest, const char* src)
{char* start = dest; // 保存 dest 的初始值  assert(dest&&src != NULL);while ((*dest++ = *src++) != '\0'){// 复制字符,直到 '\0'  }return start; // 返回目标字符串的起始地址  
}int main()
{char src[] = "Hello World!";char dest[50]; // 确保目标缓冲区足够大,以避免溢出  my_strcpy(dest, src);printf("Copied string: %s\n", dest);return 0;
}

3.strcat

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

(1)库函数

int main()
{//在hello后面加上wordchar arr[20] = "hello ";strcat(arr, "word");printf("%s\n", arr);return 0;
}

(2)模拟实现

#include <assert.h>
char* my_strcat(char* dest, const char* src)
{char* ret = dest;assert(dest && src != NULL);//a.找到目标字符串的'\0'while (*dest){dest++;}//b.源数据追加过去,包含'\0'while (*dest++ = *src++){;}return ret;  //返回目标空间的起始地址
}int main()
{//在hello后面加上wordchar arr1[20] = "hello ";char arr2[] = "world";my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

4.strcmp

  • 实现功能:用来比较两个字符串大小(比较对应位置的ASII值);
  • 基本结构:int strcmp(const char* strl, const char* str2);
  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

(1)库函数

int main()
{int ret = strcmp("abbb", "abq");   //<0//int ret = strcmp("sit", "sit");printf("%d\n", ret);return 0;
}

(2)模拟实现

#include <assert.h>
int my_strcmp(const char* s1, const char* s2)
{assert(s1&&s2 != NULL);while (*s1 == *s2){if (*s1 == '\0'){return 0;}s1++;s2++;}a.第一种写法//if (*s1 > *s2)//{//	return 1;//}//else//{//	return -1;//}//b.第二种写法:只要返回的值满足体条件即可return *s1 - *s2;
}int main()
{char* p = "abcdef";char* q = "abbb";int ret = my_strcmp(p, q);   if (ret > 0){printf("p > q\n");}else if(ret < 0){printf("p < q\n");}else{printf("p == q\n");}return 0;
}

5.strncpy

基本结构:char* strncpy(char* destination, const char* source, size t num);

参数说明:

  • dest:目标字符串的指针,即要复制到的位置。该位置必须有足够的空间来容纳复制的字符以及可能的空字符\0(如果源字符串长度小于n)。
  • src:源字符串的指针,即要从中复制的字符串。
  • n:要复制的最大字符数(包括空字符\0,但实际上strncpy并不保证在复制n个字符后自动添加\0)。

功能:将源字符串src的前n个字符复制到目标字符串dest中。

int main()
{char arr1[10] = "aaaaaaaa";char arr2[] = "hhhh";strncpy(arr1, arr2, 2);printf("%s\n", arr1);   //hhaaaaaareturn 0;
}

6.strncat

基本结构:char* strncat(char*destination, const char* source, size_t num)

参数说明:

  • dest:目标字符串的指针,即要将源字符串追加到的位置。该位置必须有足够的空间来容纳追加的字符以及额外的空字符\0
  • src:源字符串的指针,即要追加的字符串。
  • n:要追加的最大字符数。如果源字符串的长度小于n,则会将源字符串的全部字符追加到目标字符串中;如果源字符串的长度大于或等于n,则只会追加前n个字符。

功能:strncat函数将源字符串src的前n个字符追加到目标字符串dest的末尾,并在追加完成后在dest的末尾添加一个空字符\0。

int main()
{char arr1[10] = "hello ";char arr2[] = "word";strncat(arr1, arr2, 3);printf("%s\n", arr1);   //hello worreturn 0;
}

7.strncmp

基本结构:int strncmp(const char* strl, const char* str2, size_t num );

参数说明:

  • str1:指向第一个要比较的字符串的指针。
  • str2:指向第二个要比较的字符串的指针。
  • n:要比较的字符数。

实现功能:strncmp函数逐个比较str1str2的前n个字符(或直到遇到第一个空字符\0,以先到者为准)。根据比较结果,函数返回一个整数,表示两个字符串在比较的前n个字符中的相对顺序。

返回值:

  • 如果str1str2的前n个字符完全相同(或者在比较过程中遇到了空字符\0),则strncmp返回0。
  • 如果str1在字典顺序上小于str2(即str1的第一个不同字符的ASCII值小于str2的对应字符),则strncmp返回一个负整数。
  • 如果str1在字典顺序上大于str2(即str1的第一个不同字符的ASCII值大于str2的对应字符),则strncmp返回一个正整数。
int main()
{char* p = "abcdef";char* q = "abcqwert";//int ret = strcmp(p, q);int ret = strncmp(p, q, 1);printf("%d\n", ret);return 0;
}

8.strstr

基本结构:char* strstr(const char*,const char*);

参数:

  • str1:被查找的字符串(目标字符串)。
  • str2:要查找的子字符串。

功能:用于判断一个字符串(str2)是否是另一个字符串(str1)的子串。如果str2是str1的子串,则函数返回str2在str1中首次出现的地址(即指向str1中str2首次出现位置的指针);如果str2不是str1的子串,则返回NULL。

(1)库函数

int main()
{char arr1[] = "abcdef";char arr2[] = "bcd";在arr1中查找是否包含arr2数组char* ret = strstr(arr1, arr2);if (ret == NULL){printf("没找到\n");}else{printf("找到了:%s\n", ret);}return 0;
}

(2)模拟实现

#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* s1 = NULL;const char* s2 = NULL;char* cp = str1;while (*cp ){s1 = cp;s2 = str2;while (*s1 && *s2 && (*s1 == *s2)){s1++;s2++;}if (*s2 == '\0')   //找到了{return (char*)cp;}cp++;}return NULL;
}int main()
{char arr1[] = "abbbbcdef";char arr2[] = "bbc";//在arr1中查找是否包含arr2数组char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("没找到\n");}else{printf("找到了:%s\n", ret);}return 0;
}

9.strtok

  • 功能:切割一个字符串
  • 结构:char* strtok(char* str, const char* sep);
  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为 NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为 NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回NULL指针
int main()
{char arr[] = "3033433807@qq.com";char* p = "@.";char tmp[20] = { 0 };strcpy(tmp, arr);char* ret = NULL;(1)第一种写法:麻烦//ret = strtok(tmp, p);//printf("%s\n", ret);//ret = strtok(NULL, p);//printf("%s\n", ret);//ret = strtok(NULL, p);//printf("%s\n", ret);//第二种写法:简洁for (ret = strtok(tmp, p); ret != NULL; ret=strtok(NULL,p)){printf("%s\n", ret);}return 0;
}

10.strerror

  • 结构:char* strerror(int errnum );
  • 功能:返回错误码,所对应的错误信息。
  • 使用库函数,调用失败的时候,都会设置错误码
  • int errno - 全局变量
  • 和它对应的一个库函数:perror - 直接打印错误信息,没得错误码
#include <errno.h>
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));FILE* pf = fopen("test.txt", "r");if (pf == NULL){//printf("%s\n", strerror(errno));perror("fopen");return 1;}return 0;
}


http://www.ppmy.cn/ops/94255.html

相关文章

合合信息的OCR技术在智能文档处理方面有哪些具体的应用案例?

智能文档处理(IDP)是利用人工智能技术,自动从复杂的非结构化和半结构化文档中抽取关键数据,并将其转换成结构化数据的技术。能够自动识别、提取并结构化处理文档中的关键信息。这种技术通常基于自然语言处理&#xff08;NLP&#xff09;和计算机视觉等先进技术&#xff0c;可以…

003 启动后端商品微服务

文章目录 renren-fast模块application.ymlapplication-dev.yml cubemall-common父模块pom cubemall-product模块pomapplication.yml.gitignore renren-generatorapplication.yml cube_admin.sql https://gitee.com/renrenio https://baomidou.com/getting-started/install/ htt…

操作系统中的进程:深入解析与理解

文章目录 一、什么是进程&#xff1f;&#x1f914;二、进程的特性 &#x1f31f;三、进程的组成 &#x1f9e9;四、进程的状态与转换 &#x1f504;&#x1f500;五、进程的调度与管理 &#x1f527;&#x1f500;六、代码示例&#xff08;C&#xff09;创建进程进程等待&…

Vue(四)——总结

渐进式JavaScript框架 Vue.js是一套构建用户界面&#xff08;UI&#xff09;的渐进式JavaScript框架。 1、库和框架的区别&#xff1f; 库&#xff1a;库是提供给开发者的一个封装好的特定于某一方面的集合&#xff08;方法和函数&#xff09;&#xff0c;库没有控制权&…

探索Golang的微观世界:用net/trace包追踪网络操作

标题&#xff1a;探索Golang的微观世界&#xff1a;用net/trace包追踪网络操作 在Go语言的丰富生态系统中&#xff0c;net/trace包是一个强大的工具&#xff0c;它允许开发者深入网络请求的微观世界&#xff0c;洞察每一次数据的流动和操作的执行。本文将详细探讨如何使用net/…

前端学习笔记-JS篇-04

函数 为什么需要函数&#xff1f; 函数:function,是被设计为执行特定任务的代码块 说明:函数可以把具有相同或相似逻辑的代码“包裹”起来&#xff0c;通过函数调用执行这些被“包裹”的代码逻辑&#xff0c;这么做的优势是有利于精简代码方便复用。比如前面使用的alert()、p…

【九芯电子】智能声控台灯语音模块,低成本语音识别芯片

在当今数字化时代&#xff0c;智能家居已经逐渐成为现代生活中的一部分。从温度调节到安全监控&#xff0c;我们对家居设备的控制已经更加便捷。然而&#xff0c;随着生活节奏的加快&#xff0c;用户对于更便捷的家庭控制方式的需求也在不断增加。针对这一关键的问题&#xff0…

linux系统编程——线程

一、线程 1、定义 轻量级的进程。进程就相对的变成了重量级的进程&#xff08;单个控制线程&#xff09;。 2、组成 线程ID&#xff08;tid&#xff09;、程序计数器、寄存器集合、栈、 3、线程与进程比较 &#xff08;1&#xff09;线程成为CPU执行的最小单元&#xff1…