字符函数strlen、strcpy、strcat、strcmp、strstr、strtok、 strerror和perror函数

目录

 1、strlen函数

strlen函数的模拟实现

2、strcpy函数

strcpy函数的模拟实现 

strncpy函数

 strncpy函数的模拟实现

3、srtcat函数

strcat函数的模拟实现 

strncat函数

strncat函数的模拟实现

4、strcmp函数

strcmp函数的模拟实现

strncmp函数

5、strstr函数

strstr函数的模拟实现

6、strtok函数

7、strerror函数

 8、perror函数


 1、strlen函数

描述:

C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。

 函数声明:

size_t strlen(const char *str)

 返回值:

该函数返回字符串的长度。

 用法:
 

#include <stdio.h>
#include <string.h>

int main ()
{
   char str[50];
   int len;

   strcpy(str, "This is runoob.com");

   len = strlen(str);
   printf("|%s| 的长度是 |%d|\n", str, len);
   
   return(0);
}

结果:

strlen函数的模拟实现

#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char arr[] = { "hello world!" };
	int red = my_strlen(arr);
	printf("%d\n", red);
	return 0;
}

2、strcpy函数

描述:

C 库函数 char *strcpy(char *dest, const char *src) 把 src 所指向的字符串复制到 dest

需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。

函数声明:

char *strcpy(char *dest, const char *src)

  参数:

  • dest -- 指向用于存储复制内容的目标数组。
  • src -- 要复制的字符串。

返回值:

该函数返回一个指向最终的目标字符串 dest 的指针。

 用法:

#include <stdio.h>
#include <string.h>
 
int main ()
{
  char str1[]="Sample string";
  char str2[40];
  char str3[40];
  strcpy (str2,str1);
  strcpy (str3,"copy successful");
  printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
  return 0;
}

 结果:

strcpy函数的模拟实现 

#include <stdio.h>
#include <assert.h>

char* my_strcpy(char* dest, const char* str)
{
	char* ret = dest;//把dest的地址给ret
	assert(dest != NULL);
	assert(str != NULL);
	while (*dest++ = *str++)//将str上的值赋给dest
	{
		;
	}
	return ret;//ret是一个插入类型的指针,里面存储着dest的地址
}

int main()
{
	char arr1[] = { "hello world!" };
	char arr2[100] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

strncpy函数

与strcpy相似,只是多了一个限制复制字符个数的条件

声明:

char *strncpy(char *dest, const char *src, size_t n)

 n -- 要从源中复制的字符数。

用法:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = { "hello world" };
	char arr2[20] = { 0 };
	int n = 5;
	strncpy(arr2, arr1, n);
	printf("%s\n", arr2);
	return 0;
}

 strncpy函数的模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strncpy(char* dest, char* str, size_t n)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(str != NULL);
	int i = 0;
	for (i = 0; i < n; i++)
	{
		*dest++ = *str++;
	}
	return ret;
}

int main()
{
	char arr1[20] = "hello world";
	char arr2[20] = { 0 };
	
	int num = 7;
	my_strncpy(arr2, arr1, num);
	printf("%s\n", arr2);
	return 0;
}

 结果:

3、srtcat函数

描述:

C 库函数 char *strcat(char *dest, const char *src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

 函数声明:

char *strcat(char *dest, const char *src)

 参数:

  • dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
  • src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。

返回值:

该函数返回一个指向最终的目标字符串 dest 的指针。 

用法:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = { 0 };
	char arr2[20] = { 0 };
	strcpy(arr1, "world hello");
	strcpy(arr2, "hello ");
	strcat(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

strcat函数的模拟实现 

#include <stdio.h>
#include <assert.h>

char* my_strcat(char* dest, const char* str)
{
	char* ret = dest;//把dest的地址给ret
	assert(dest != NULL);
	assert(str != NULL);

	while (*dest)
	{
		dest++;//遍历完dest
	}
	//在遍历完dest的基础上再给dest赋值
	while (*dest++ = *str++)
	{
		;
	}
	return ret;//ret是一个char类型的指针,里面存储着dest的地址
}

int main()
{
	char arr1[] = { "hello world!" };
	char arr2[100] = { "hello " };//目标空间一定要足够,不然会报错
	my_strcat(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

strncat函数

与strcat相似,只是多了一个限制追加字符个数的条件

函数声明:

char *strncat(char *dest, const char *src, size_t n)

n -- 要追加的最大字符数。

用法:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = { 0 };
	char arr2[20] = { 0 };
	strcpy(arr1, "world hello");
	strcpy(arr2, "hello ");
	int num = 5;
	strncat(arr2, arr1,num);
	printf("%s\n", arr2);
	return 0;
}

结果:

strncat函数的模拟实现

#include <stdio.h>
#include <string.h>
#include <assert.h>

char* my_strncat(char* dest, char* str, size_t n)
{
	assert(dest != NULL);
	assert(str != NULL);
	char* ret = dest;

	while (*dest)
	{
		dest++;
	}
	for (int i = 0; i < n; i++)
	{
		*dest++ = *str++;
	}
	return ret;
}

int main()
{
	char arr1[20] = { 0 };
	char arr2[20] = { 0 };
	strcpy(arr1, "world hello");
	strcpy(arr2, "hello ");
	int num = 5;
	my_strncat(arr2, arr1,num);
	printf("%s\n", arr2);
	return 0;
}

结果:

4、strcmp函数

描述:

C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。

 声明:

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

参数:

  • str1 -- 要进行比较的第一个字符串。
  • str2 -- 要进行比较的第二个字符串。

返回值:

  • 如果返回值小于 0,则表示 str1 小于 str2。
  • 如果返回值大于 0,则表示 str1 大于 str2。
  • 如果返回值等于 0,则表示 str1 等于 str2。

用法:
 

#include <stdio.h>
#include <string.h>
 
int main ()
{
   char str1[15];
   char str2[15];
   int ret;
 
 
   strcpy(str1, "abcdef");
   strcpy(str2, "ABCDEF");
 
   ret = strcmp(str1, str2);
 
   if(ret < 0)
   {
      printf("str1 小于 str2");
   }
   else if(ret > 0) 
   {
      printf("str1 大于 str2");
   }
   else 
   {
      printf("str1 等于 str2");
   }
   
   return(0);
}

strcmp函数的模拟实现

#include <stdio.h>
#include <assert.h>
#include <string.h>
int my_strcmp( const char* s1,const char* s2)
{
	assert(s1 != NULL);
	assert(s2 != NULL);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
			return 0;
		s1++;
		s2++;
	}
	return *s1 - *s2;
}
int main()
{
	char str1[15];
	char str2[15];
	strcpy(str1, "abcdef");
	strcpy(str2, "ABCDEF");
	int ret = my_strcmp(&str1, &str2);
	if (ret > 0)
	{
		printf("str1 > str2\n");
	}
	else if (ret < 0)
	{
		printf("str1 < str2\n");
	}
	else
	{
		printf("str1 = str2\n");
	}
	return 0;
}

strncmp函数

函数声明:

int strncmp(const char *str1, const char *str2, size_t n)

 用法:

#include <stdio.h>
#include <string.h>

int main ()
{
   char str1[15];
   char str2[15];
   int ret;


   strcpy(str1, "abcdef");
   strcpy(str2, "ABCDEF");

   ret = strncmp(str1, str2, 4);

   if(ret < 0)
   {
      printf("str1 小于 str2");
   }
   else if(ret > 0) 
   {
      printf("str2 小于 str1");
   }
   else 
   {
      printf("str1 等于 str2");
   }
   
   return(0);
}

5、strstr函数

描述:

C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。

 声明:

char *strstr(const char *haystack, const char *needle)

 参数:

  • haystack -- 要被检索的 C 字符串。
  • needle -- 在 haystack 字符串内要搜索的小字符串。

 返回值:

该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。

 用法:

#include <stdio.h>
#include <string.h>
int main()
{
	const char haystack[20] = "notebook";
	const char needle[10] = "book";
	char* ret = strstr(haystack, needle);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else
	{
		printf("找不到\n");
	}
	return 0;
}

strstr函数的模拟实现

这个函数的模拟实现就比较麻烦了。我们来仔细分析一下。

先来看函数的定义:

char* my_strstr(const char* haystack, const char* needle)

haystack和needle分别指向字符串的首字母,如果找到相同的字符,haystack和needle向后移一位,如果没有找到相同的,haystack向后移一位。如果全部找到,就要返回 b 的地址。当haystack和needle分别向后找的时候,没人会记得b的地址,所以就要有一个指针记录开始匹配的位置。

但是还有一种情况:

haystack找到n的时候和needle找到 t 的时候,两个不匹配,就要重匹配,needle就要重新回去,所以还要有一个指针记录needle的起始位置.同理也还要一个指针记录haystack的起始位置。

#include <stdio.h>

char* my_strstr(const char* haystack, const char* needle)
{
	const char* str1 = NULL;//str1 用来记录haystack
	const char* str2 = NULL;//str2 用来记录needle
	const char* count = haystack;// count记录 查找的起始位置

	while (*count)
	{
		str1 = count; //将查找的起始位置给str1
		str2 = needle;//将被查找的起始位置给str2
		while (*str1 != '\0' && *str2 != '\0' && *str1 == *str2)
		{   //*str1为\0,就说明后面没有可以查找的了
			//*str2为\0,就说明已经找完了
			str1++;
			str2++;
		}
		if (*str2 == '\0')
		{
			return (char*)count;//查找完了就返回查找的起始位置count
		}

		count++; //查找不匹配,查找起始位置就往后移一位
	}
	return NULL; //找不到返回空指针
}
int main()
{
	char arr1[20] = "nonotebook";
	char arr2[10] = "note";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else
	{
		printf("找不到\n");
	}
	return 0;
}

6、strtok函数

描述:

C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。

声明:

char *strtok(char *str, const char *delim)

参数:

  • str -- 要被分解成一组小字符串的字符串。
  • delim -- 包含分隔符的 C 字符串。

返回值:

该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

 用法:

#include <string.h>
#include <stdio.h>

int main() {
	char str[80] = "This is - www.runoob.com - website";
	const char s[2] = "-";
	char* token;

	/* 获取第一个子字符串 */
	token = strtok(str, s);
	
	/* 继续获取其他的子字符串 */
	while (token != NULL) {
		printf("%s\n", token);

		token = strtok(NULL, s);
	}

	return(0);
}

7、strerror函数

描述:

C 库函数 char *strerror(int errnum) 从内部数组中搜索错误号 errnum,并返回一个指向错误消息字符串的指针。strerror 生成的错误字符串取决于开发平台和编译器。

声明:

char *strerror(int errnum)

参数:

  • errnum -- 错误号,通常是 errno

 返回值:

该函数返回一个指向错误字符串的指针,该错误字符串描述了错误 errnum。

 strerror函数可以把参数部分错误码对应的信息的字符串地址返回来。

在不同的系统和C语言标准库的实现中都规定了一些错误码,一般是放在error.h这个头文件中说明的,C语言程序启动的时候就会使用一个全面的变量 errno 来记录程序的当前错误码,只不过程序启动的时候 errno 是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会将对应的错误码,存放在 errno 中,而一个错误码的数字是整数很难理解是什么意思,所以每一个错误码都是有对应的错误信息的。 strerror 函数就可以将错误对应的错误信息字符串的地址返回。

在Windouws和VS2022环境下

#include <errno.h>
#include <string.h>
#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 0; i <= 10; i++) {
		printf("%s\n", strerror(i));
	}
	return 0;
}

结果:

用法:

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main ()
{
   FILE *fp;

   fp = fopen("file.txt","r");
   if( fp == NULL ) 
   {
      printf("Error: %s\n", strerror(errno));
   }
   
  return(0);
}

结果:

 8、perror函数

描述:

C 库函数 void perror(const char *str) 把一个描述性错误消息输出到标准错误 stderr。首先输出字符串 str,后跟一个冒号,然后是一个空格。

声明:

void perror(const char *str)

参数:

  • str -- 这是 C 字符串,包含了一个自定义消息,将显示在原本的错误消息之前。

注意,这里str是一个C字符串,就要用C字符串的格式来写

返回值:

该函数没有返回值。

 用法:

#include <stdio.h>

int main ()
{
   FILE *fp;

   /* 首先重命名文件 */
   rename("file.txt", "newfile.txt");

   /* 现在让我们尝试打开相同的文件 */
   fp = fopen("file.txt", "r");
   if( fp == NULL ) {
      perror("Error: ");
      return(-1);
   }
   fclose(fp);
      
   return(0);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

anaconda创建了虚拟python环境,且安装了pytorch,但是pycharm中import torch运行时报错

报错如下&#xff1a; C:\Users\tashi\.conda\envs\test1\python.exe D:\project\python\transformer\main.py C:\Users\tashi\.conda\envs\test1\lib\site-packages\numpy\__init__.py:127: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL init…

AI虽强,搜索引擎仍不可或缺

AI 领域正以前所未有的速度发展&#xff0c;大模型的发布变得愈发频繁&#xff0c;模型的规模也在持续扩大。如今&#xff0c;大模型的起点已经攀升至数十亿参数&#xff08;数十 B&#xff0c;B 是 Billion 的简写&#xff0c;10 亿&#xff09;&#xff0c;其功能之广泛&…

二、Python接口自动化fixture和conftest

1、fixture详解 fixture概念fixture是 pytest 用于将测试前后进行预备、清理工作的代码处理机制。 fixture相对于setup和teardown来说有以下几点优势: • fixure命名更加灵活&#xff0c;局限性比较小 • conftest.py 配置里面可以实现数据共享&#xff0c;不需要import就能自…

嵌入式sqlite3交叉编译移植

操作系统:Ubuntu20.04 下载sqlite3代码,下载版本3.30.00 wget https://www.sqlite.org/2019/sqlite-amalgamation-3300000.zip 或者https://download.csdn.net/download/benico/89127678 为什么下载amalgamation版本,不下载autoconf版本? 根据我的编译实验,同版本sql…

错题记录-华为海思

华为 海思数字芯片 参考 &#xff1a;FPGA开发/数字IC笔试系列(5) 华为海思IC笔试解析 FPGA开发/数字IC笔试系列(6) 华为海思IC笔试解析 SystemVerilog Function与Task的区别 $readmemh与$readmemb这两个系统任务是用来从指定文件中读取数据到寄存器数组或者RAM、ROM中。除了…

stm32与esp8266WIFI模块

硬件介绍 WIFI模块ESP-01S 使用AT指令控制1-ESP8266-AT指令初试化及部分基础知识_ch_pd-CSDN博客 项目需求 通过ESP-01SWIFI模块控制LED状态模拟插座 串口1用于与ESP8266通讯&#xff0c;串口2连接PC&#xff0c;用于打印log&#xff0c;查看系统状态 项目接线 将WIFI模块的…

LLM大语言模型微调方法和技术汇总

本文详细介绍了机器学习中的微调技术&#xff0c;特别是在预训练模型上进行微调的方法和技术。文章首先解释了什么是微调&#xff0c;即在预训练模型的基础上&#xff0c;通过特定任务的数据进行有监督训练&#xff0c;以提高模型在该任务上的性能。随后&#xff0c;详细介绍了…

Sonatype Nexus 服务器迁移

因为服务器的升级和调整&#xff0c;有时候会对安装 Sonatype Nexus 的服务器进行迁移到新服务器上。 从技术架构上来说&#xff0c;Sonatype Nexus 我们使用的是 AWS 的存储&#xff0c;所以我们并不需要拷贝大量的数据。 文件夹结构 在备份和恢复之前&#xff0c;我们需要…

OpenHarmony开源三方库的cmake在IDE上直接引用的问题

前言 DevEco Studio的native工程的C/C部分当前只支持cmake脚本的编译&#xff0c;工程的目录结构如下图所示 在工程中引用第三方库有如下三种方式&#xff0c; 一、find_package模式 通过find_package&#xff0c;可以在指定目录下去搜索已安装的库&#xff08;三方库构建完后…

数字IC/FPGA——亚稳态及跨时钟域

什么是亚稳态亚稳态会造成什么平均故障间隔时间如何解决亚稳态同步时钟和异步时钟单bit电平信号如何跨时钟域单bit脉冲信号如何跨时钟域多bit信号如何跨时钟域 目录 一、亚稳态1.基本概念2.危害3.平均故障时间4.解决亚稳态的方法 二、跨时钟域1.同步电路和异步电路&#xff08;…

Tuxera Ntfs for mac 2023中文解锁版安装、密钥下载与激活教程 Tuxera激活码 tuxera破解

Tuxera Ntfs for mac2023是Mac中专用于读写外置存储的工具&#xff0c;具有强大的磁盘管理和修复功能&#xff0c;它在Mac上完全读写NTFS格式硬盘&#xff0c;快捷的访问、编辑、存储和传输文件。能够在 Mac 上读写 Windows NTFS 文件系统。Tuxera NTFS 实现在Mac OS X系统读写…

【opencv】示例-npr_demo.cpp 非真实感渲染:边缘保留平滑、细节增强、铅笔素描/彩色铅笔绘图和风格化处理...

Edge Preserve Smoothing- Using Normalized convolution Filter Edge Preserve Smoothing-Using Recursive Filter Detail Enhancement Pencil sketch/Color Pencil Drawing Stylization /* * npr_demo.cpp * * 作者: * Siddharth Kherada <siddharthkherada27[at]gmail[do…

前端小技巧之轮播图

文章目录 功能htmlcssjavaScript图片 设置了一点小难度&#xff0c;不理解的话&#xff0c;是不能套用的哦&#xff01;&#xff01;&#xff01; &#xff08;下方的圆圈与图片数量不统一&#xff0c;而且宽度是固定的&#xff09; 下次写一些直接套用的&#xff0c;不整这些麻…

杭州掀起快递物流创新浪潮,2024长三角快递物流展7月共绘智慧物流新蓝图

杭州&#xff0c;作为中国的电商之都&#xff0c;近年来在快递物流行业背景与应用方面取得了显著的发展。随着电子商务的迅猛增长&#xff0c;杭州的快递物流行业迅速崛起&#xff0c;成为支撑电商产业发展的重要力量。 2024长三角&#xff08;杭州&#xff09;快递物流供应链与…

b站江科大stm32笔记(持续更新)

b站江科大stm32笔记&#xff08;持续更新&#xff09; 片上资源/外设引脚定义表启动配置推挽开漏oc/od 门漏极/集电极 电阻的上拉下拉输入捕获输入捕获通道主从触发模式输入捕获基本结构PWMI基本结构PWMPSC ARR CRR输入捕获模式测频率TIM_PrescalerConfig()初始化输入捕获测频法…

AI PC元年,华为的一张航海图、一艘渡轮和一张船票

今天&#xff0c;从学术研究者到产业投资者&#xff0c;无不认为大模型掀起了一场人工智能的完美风暴。 所谓“完美风暴”&#xff0c;指的是一项新技术的各个要素&#xff0c;以新的方式互相影响、彼此加强&#xff0c;组合在一起形成了摧枯拉朽般的力量。 而我们每个人&#…

Spark-Scala语言实战(16)

在之前的文章中&#xff0c;我们学习了三道任务&#xff0c;运用之前学到的方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&#x…

(N-149)基于微信小程序网上商城系统

开发工具&#xff1a;IDEA、微信小程序 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 前端技术&#xff1a;vue、uniapp 服务端技术&#xff1a;springbootmybatisredis 本系统分微信小程序和管理后台两部分&a…

使用Pandas实现股票交易数据可视化

一、折线图&#xff1a;展现股价走势 1.1、简单版-股价走势图 # 简洁版import pandas as pdimport matplotlib.pyplot as plt# 读取CSV文件df pd.read_csv(../数据集/格力电器.csv)data df[[high, close]].plot()plt.show() 首先通过df[[high,close]]从df中获取最高价和收盘…

【一招鲜】-阿里云服务器安全更新 RHSA-2021:3889: java-1.8.0-openjdk 安全和BUG修复更新

形似这种&#xff1a; RHSA-2021:3889: java-1.8.0-openjdk 安全和BUG修复更新 #1 查看可更新的软件java yum list updates |grep java #2 如果有可更新软件&#xff0c;则进行更新 yum -y update java-1.8.0-openjdk.x86_64 形似这种&#xff1a; RHSA-2021:4782: openssh …