字符串与相应函数(下)

字符串处理函数分类

  • 求字符串长度:strlen
  • 长度不受限制的字符串函数:strcpy,strcat,strcmp
  • 长度受限制的字符串函数:strncpy,strncat,strncmp
  • 字符串查找:strstr
  • 字符串切割:strtok
  • 错误信息报告:strerror
  • 字符操作,内存操作函数:memcpy,memmove,memset,memcmp

strstr

strstr函数是C标准库中的一个字符串处理函数,用于在一个字符串中查找子字符串的第一次出现位置。strstr函数用于在字符串中查找子字符串的第一次出现位置。如果找到,则返回指向该位置的指针;如果未找到,则返回NULL

strstr函数的特点

strstr函数的模拟实现

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>
#include<assert.h>char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);if (str2 == "\0"){return (char*)str1;}const char* s1 = str1;const char* s2 = str2;const char* cp = str1;while (*cp){s1 = cp;s2 = str2;while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2)){s1++;s2++;}if (*s2 == '\0'){return (char*)cp;}cp++;}return NULL;
}int main()
{char arr1[] = "aabbbcdef";char arr2[] = "bbc";char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);}return 0;
}

strstr函数的使用

#define  _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <string.h>int main()
{char str[] = "This is a simple string";char* pch;pch = strstr(str, "simple");if (pch != NULL)strncpy(pch, "sample", 6);puts(str);return 0;
}

strtok

strtok函数是C标准库中的一个字符串处理函数,它主要用于将输入字符串按照指定的分隔符进行分割,并返回每个子字符串的指针。这个函数非常适合处理各种常见的文本分割任务,如路径分隔、配置文件解析和数据文件处理

strtok函数的特点

字符串破坏:strtok函数会修改原始字符串,将其分割后的部分用\0字符填充,因此原始字符串在分割后会失去原有的形式。

  • 线程安全性:strtok函数不是线程安全的,因为它使用了静态分配的空间来存储被分割的字符串位置。这意味着在多线程环境中使用strtok函数可能会导致不可预测的行为
  • 分隔符的多样性:strtok函数支持多个分隔符,只需在delim中列出所有分隔符即可

strtok函数的使用

 #define  _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <string.h>int main()
{char arr[] = "198.168.120.50";char* p = ".";char buf[20] = { 0 };strcpy(buf, arr);char* ret = NULL;for (ret = strtok(buf, p);ret != NULL;ret = strtok(NULL, p)){printf("%s\n", ret);}return 0;
}

strerror

strerror函数是C语言中的一个函数,用于将指定的错误码转换为对应的错误信息字符串。

strerror函数的特点

  • strerror函数的头文件:strerror函数定义在errno.h头文件中,因此在使用该函数之前,必须包含这个头文件。
  • strerror函数的返回值 :strerror函数的返回值是一个指向错误消息字符串的指针,这个消息字符串即为出错信息的字符串。如果函数调用成功,返回值是指向错误信息字符串的指针;如果发生错误,则返回一个空指针(NULL)。
  • strerror函数的注意事项 :需要注意的是,strerror函数不是线程安全的,因为在多线程环境中,多个线程可能会同时调用strerror函数并覆盖errno的值。因此,在多线程程序中,建议使用strerror_r函数,它是strerror的线程安全版本。
  • strerror函数的使用场景:strerror函数通常在系统调用或库函数出错时使用。当这些函数返回错误时,会设置errno变量,此时可以使用strerror函数将errno的值转换为人类可读的错误信息,便于调试和日志记录。

strerror函数的使用

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>
#include<errno.h>int main()
{//打开文件FILE* pf = fopen("text.exe", "r");if (pf == NULL){printf("%s\n", strerror(errno));}//读文件//关闭文件fclose(pf);pf = NULL;return 0;
}

输出结果:

在此我们看见我们还需要写一个输出语句,那么我们还可以使用perror函数,可以更加直接明了的发现错误

perror=printf+error

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>
#include<errno.h>int main()
{//打开文件FILE* pf = fopen("text.exe", "r");if (pf == NULL){//printf("%s\n", strerror(errno));perror("fopen");return 1;}//读文件//关闭文件fclose(pf);pf = NULL;return 0;
}

输出结果:

memcpy

memcpy是C语言中的一个标准库函数,用于将源内存区域的内容复制到目标内存区域。

memcpy函数的特点

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

memcpy函数与strcpy函数的区别

1. 复制内容

  • strcpy:专门用于复制字符串,它会一直复制直到遇到源字符串中的 '\0'结束符。
  • memcpy:可以复制任意内容,如字符数组、整型、结构体、类等。它按照指定的字节数进行复制,而不是基于 '\0' 结束符。

2. 函数原型

  • strcpy: char* strcpy(char* dest, const char* src); ,返回指向目标缓冲区 `dest` 的指针。
  • memcpy:void* memcpy(void* dest, const void* src, size_t n); ,其中 n 是要复制的字节数,同样返回指向目标缓冲区 dest 的指针 。

3. 安全性

  • strcpy :由于其不检查目标缓冲区的大小,若源字符串长度超过了目标缓冲区的大小(不包括 '\0' ),就 会发生缓冲区溢出,这是一个常见的安全隐患。例如,目标缓冲区只能容纳 5 个字符,而源字符串有 10 个字符,使用 ` strcpy 就会导致溢出 。
  • memcpy :虽然它提供了复制字节数的选项,但如果指定了错误的字节数或目标缓冲区大小不足,也可能导致问题。不过,由于其提供了明确的字节数,所以相比于 strcpy ,它在某些情况下可能更安全 。

4. 用途

  • strcpy :主要用于字符串的复制。当明确知道要复制的是字符串时,使用 strcpy 较为方便。
  • memcpy :用于复制任意类型的内存块,特别是当需要复制的数据中可能包含 '\0' 字符时(因为 strcpy 在遇到 '\0' 时会停止复制)。例如,复制一个包含图像数据的内存块,就需要使用 memcpy 。

5. 实现方式

  • strcpy :通过逐个字符复制直到遇到 '\0' 结束符来实现字符串的复制。
  • memcpy :通过逐个字节复制来实现内存块的复制,直到达到指定的字节数 `n`。在地址不对齐的情况下,它是一个字节一个字节地拷,地址对齐以后,就会使用 CPU 字长(32bit 或 64bit)来拷,还会根据 CPU 的类型选择一些优化的指令来进行拷贝 [[4]()]。

6. 效率 :在拷贝相同字符串和字节数时,`strcpy` 的效率略高于 `memcpy`。不过 `memcpy` 是一个效率较高的内存拷贝函数,其实现与 CPU 类型、操作系统、cLib 相关。

memcpy函数的使用

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };int arr2[10] = { 0 };memcpy(arr2, arr1, 20);int i = 0;for (i = 0;i < 5;i++){printf("%d ", arr2[i]);}return 0;
}

memmove

memmove函数是C语言中用于内存操作的一个重要工具,它主要用于从源内存区域拷贝一定数量的字节到目标内存区域。memmove函数的一个显著特点是它可以处理源内存区域和目标内存区域重叠的情况,这使得它在处理某些特定的内存操作时非常有用

memmove函数的特点

1. 处理内存重叠

Memmove函数的一个显著特点是它可以处理源内存区和目标内存区重叠的情况。这意味着,如果源内存区和目标内存区的部分区域重叠,memmove仍然可以正确地复制字节,而不会像memcpy那样导致数据损坏。

2. 内存操作的安全性

由于memmove能够处理内存重叠,它在进行内存操作时更加安全。当源和目标内存区域重叠时,memmove会从高地址向低地址进行拷贝,以确保数据的正确性和完整性。

3. 返回值

Memmove函数的返回值是指向目标内存区的指针。这一点与memcpy相同。

4. 使用场景

Memmove通常在需要处理内存重叠的情况下使用,例如在字符串操作中移动字符串,或者在数组中移动元素。它的这些特点使得它在C语言编程中成为一个非常有用的工具。

5. 实现细节

虽然memmove的具体实现可能会有所不同,但它的基本思想是使用中间缓冲区的方式来复制数据,从而允许目标和源重叠。这种实现方式确保了数据的安全复制。

memmove函数的使用

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>int main()
{char str[] = "memmove can be very useful......";memmove(str + 20, str + 15, 11);puts(str);return 0;
}

memset

memset函数的作用是将指针变量s所指向的前n字节的内存单元用一个整数c替换。这个函数通常用于新申请的内存做初始化工作,例如将一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为'''/0'.

memset函数的特点

1. 内存空间初始化

memset函数主要用于内存空间的初始化。它可以将一段内存空间全部设置为某个字符,通常用在对定义的字符串进行初始化为''或'\0'。例如,可以使用memset将一个字符数组初始化为空字符串2memset()函数及其作用_cc2530 memset(re,0,20)。

2. 清空结构体变量或数组

memset可以方便地清空一个结构类型的变量或数组。这对于大型数据结构的快速清零非常有用,避免了手动逐个成员清零的繁琐1memset()函数及其作用。

3. 字节级操作

memset函数以字节为单位进行操作,这意味着它可以将指定内存区域的每个字节设置为相同的值。这使得它非常适合用于初始化或清空原始内存块2memset()函数及其作用_cc2530 memset(re,0,20)。

4. 快速操作

对于较大的结构体或数组,memset是进行清零操作的一种最快方法。它的实现通常是优化过的,能够在较短时间内完成大量内存的初始化

memset函数的使用

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>int main()
{char str[] = "haha xixi yesyes nono.";memset(str, '@', 10);puts(str);return 0;
}

输出结果:

memcmp

memcmp 函数是C语言中的一个标准库函数,用于比较两个内存区域的内容。

memcmp函数的特点

  1. 逐字节比较:memcmp函数是按字节比较的,它逐个比较内存区域buf1和buf2的前count个字节。
  2. ASCII码比较:memcmp函数比较的是字节的ASCII码值,而不是字符的实际意义。
  3. 返回值:当buf1小于buf2时,返回值小于0;当buf1等于buf2时,返回值等于0;当buf1大于buf2时,返回值大于0。
  4. 不受字符串结束符影响:与strcmp函数不同,memcmp函数不会受到字符串结束符(如'\0')的影响,它只比较前count个字节。
  5. 适用范围:memcmp函数不仅可以用于比较字符串,还可以用于比较任何类型的内存区域,这使得它在处理二进制数据时非常有用。
  6. 效率:由于memcmp函数不需要寻找字符串结束符,因此在处理大型数据块时,它的效率通常比strcmp函数高。

memcmp函数的使用

#define  _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<string.h>int main()
{char str1[] = "abgrdsd";char str2[] = "nxcjkdbc";int n = 0;n = memcmp(str1, str2, sizeof(str1));if (n > 0)printf("str1>str2\n");else if(n == 0)printf("str1=str2\n");elseprintf("str1 < str2");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/910270.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9.thinkphp的请求

请求对象 当前的请求对象由think\Request类负责&#xff0c;该类不需要单独实例化调用&#xff0c;通常使用依赖注入即可。在其它场合则可以使用think\facade\Request静态类操作。 项目里面应该使用app\Request对象&#xff0c;该对象继承了系统的think\Request对象&#xff…

机器学习:让数据开口说话的科技魔法

在人工智能飞速发展的今天&#xff0c;「机器学习」已成为推动数字化转型的核心引擎。无论是手机的人脸解锁、网购平台的推荐系统&#xff0c;还是自动驾驶汽车的决策能力&#xff0c;背后都离不开机器学习的技术支撑。那么&#xff0c;机器学习究竟是什么&#xff1f;它又有哪…

n8n 本地部署及实践应用,实现零成本自动化运营 Telegram 频道(保证好使)

n8n 本地部署及实践应用&#xff0c;实现零成本自动化运营 Telegram 频道&#xff08;保证好使&#xff09; 简介 n8n 介绍 一、高度可定制性 二、丰富的连接器生态 三、自托管部署&#xff08;本地部署&#xff09; 四、社区驱动 n8n 的部署 一、前期准备 二、部署步…

通过 spring ai 对接 deepseek ai 大模型通过向量数据库,完成 AI 写标书及构建知识库功能的设计与开发

AI写标书及知识库构建详细设计方案 一、系统架构设计 +-------------------+ +-------------------+ +-------------------+ | 用户交互层 | | AI服务层 | | 知识库存储层 | | (Web/API) |---->| (Spring AI) |---…

【NIO番外篇】之组件 Channel

目录 一、什么是NIO Channel&#xff1f;二、常见的Channel组件及其用法1. FileChannel2. SocketChannel3. ServerSocketChannel4. DatagramChannel &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;可以多多支持一下&a…

在人工智能与计算机技术融合的框架下探索高中教育数字化教学模式的创新路径

一、引言 1.1 研究背景 在数字中国战略与《中国教育现代化 2035》的政策导向下&#xff0c;人工智能与计算机技术的深度融合正深刻地重构着教育生态。随着科技的飞速发展&#xff0c;全球范围内的高中教育都面临着培养具备数字化素养人才的紧迫需求&#xff0c;传统的教学模式…

使用Python爬虫的2大原因和6大常用库

爬虫其实就是请求http、解析网页、存储数据的过程&#xff0c;并非高深的技术&#xff0c;但凡是编程语言都能做&#xff0c;连Excel VBA都可以实现爬虫&#xff0c;但Python爬虫的使用频率最高、场景最广。 这可不仅仅是因为Python有众多爬虫和数据处理库&#xff0c;还有一个…

第五篇:Python面向对象编程(OOP)深度教程

1. 类与对象 1.1 基本概念 ​​类​​是创建对象的蓝图,定义了对象的​​属性​​(数据)和​​方法​​(行为)。​​对象​​是类的实例化实体,每个对象拥有独立的属性值和共享的类方法 ​​示例​​:定义Dog类 class Dog:species = "Canis familiaris" …