【c语言】字符函数与字符串函数(上)

大家好呀,今天给大家分享一下字符函数和字符串函数,说起字符函数和字符串函数大家会想到哪些呢??我想到的只有求字符串长度的strlen,拷贝字符串的strcpy,字符串比较相同的strcmp,今天,我要分享给大家的是我们一些其他的字符函数和字符串函数,跟着小张一起去看看吧!

文章目录

  • 前言
  • 长度不受限制的字符串函数
    • strcat
  • 长度受限制的字符串函数
    • strncpy
    • strncat
    • strncmp
  • 字符串查找
    • strstr
    • strtok
  • 错误信息报告
    • strerror
  • 模拟实现
    • strcat的模拟实现
    • strstr的模拟实现
  • 总结

前言

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串中或者字符数组 中.字符串常量 适用于那些对它不做修改的字符串函数


长度不受限制的字符串函数

strcat

功能:可以在一个字符串后面追加字符
函数声明:char *strcat( char *strDestination, const char *strSource );
头文件:string.h
参数解释以及返回值解释:第一个参数接收被追加字符串数组的地址,第二个参数是追加的内容字符串数组,返回的是追加后字符串数组的地址
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS

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

int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "gh";
	strcat(arr1, arr2);
	printf("%s", arr1);


}

注意:源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = {'a','b','c'};
	strcat(arr1, arr2);
	printf("%s", arr1);
}

在这里插入图片描述
程序发生崩溃,arr2数组如果没有’\0’的话,他会在后面地址上找到\0,在追加到arr1数组的时候,会越界放不下

字符串strcat函数不能自己给自己追加

追加前在这里插入图片描述
追加后
在这里插入图片描述
追加的时候把源数组中的‘\0’被追加字符所覆盖


长度受限制的字符串函数

strncpy

功能:拷贝num个字符从源字符串到目标空间
函数声明:char * strncpy ( char * destination, const char * source, size_t num );
头文件:string.h
参数:第一个参数为接收目标空间地址,第二个参数接收是源空间地址,返回参数是目标地址,size_t是无符号整数类型,num是拷贝字符的数目

#define _CRT_SECURE_NO_WARNINGS

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

int main()
{
	char arr1[40] = "hered ";
	char arr2[] = "ll";
	strncpy(arr1,arr2,2);
	printf("%s",arr1);
}

在这里插入图片描述

如果源字符小于要拷贝的个数会怎么样??

int main()
{
	char arr1[40] = "hered+++++++++ ";
	char arr2[] = "ll";
	strncpy(arr1, arr2, 10);
	printf("%s", arr1);
}

在这里插入图片描述
在这里插入图片描述

注意:拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。


strncat

功能:追加num个字符从源字符串到目标空间。
声明:char * strncat ( char * destination, const char * source, size_t num );
头文件:string.h
参数:第一个参数为接收目标空间地址,第二个参数接收是源空间地址,返回参数是目标地址,size_t是无符号整数类型,num是追加字符的数目

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[40] = "hello ";
	char arr2[13] = "shuxiansheng";
	strncat(arr1, arr2, 3);
	printf("%s",arr1);
}

在这里插入图片描述

strncat可以追加自己

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[40] = "hello ";
	char arr2[13] = "shuxiansheng";
	strncat(arr1, arr1, 5);
	printf("%s",arr1);
}

在这里插入图片描述


strncmp

功能:可以比较指定个数的字符串比较
声明:int strncmp ( const char * str1, const char * str2, size_t num );
头文件:string.h
参数:第一个参数接收第一个字符串地址,第二个参数接收第二个字符串地址,第三个参数为比较字符的个数,比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[6] = "hello";
	char arr2[] = "helld";
	int ret=strncmp(arr1, arr2, 4);
	printf("%d", ret);
}

在这里插入图片描述

比较前四个字符,由于前四个字符相同,返回0,比较五个字符,o的ascll码值大于d的ascll码值返回1;


字符串查找

strstr

功能:查找子串
声明: char * strstr ( char * str1, const char * str2 );
头文件string.h
参数:第一个参数接收被查找的字符串的首地址,第二个参数疑似子串的字符串的首地址
如果是子串的话,返回字符串中子串的首地址,不是子串的话返回空指针在这里插入图片描述

代码

int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "fg";
	char *p=strstr(arr1,arr2);//保存返回子串的首地址
	if (p)
	{
		printf("是子串:%s", p);
	}
	else
	{
		printf("不是子串");
	}

}

编译运行

在这里插入图片描述
在这里插入图片描述


strtok

功能:分隔子串
声明:char * strtok ( char * str, const char * sep );
头文件:string.h
参数:第一个参数接收被分解字符串的地址,第二个参数中接收的是字符串中分隔符的地址,返回被分隔子串的首地址

代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello@qq.com";
	char arr2[] = "@.";
   strtok(arr1, arr2);
   printf("%s", arr1);
}

编译运行
在这里插入图片描述

第一个参数指定一个字符串,它包含了0个或者多个由arr2字符串中一个或者多个分隔符分割的标记。
strtok函数找到arr1中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
strtok函数的第一个参数不为 NULL ,函数将找到arr1中第一个标记,strtok函数将保存它在字符串中的位置(strtok函数在内部维护了一个静态变量保存这个位置)。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针

代码展示

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello@qq.com";
	char arr2[] = "@.";
	printf("%s\n", strtok(arr1, arr2));

   printf("%s\n", strtok(NULL, arr2));

	printf("%s\n", strtok(NULL, arr2));
   
}

编译运行
在这里插入图片描述

修改:我们可以将字符串arr1传给strtok函数,第一个@分隔符。strtok函数返回字符串中第一个遇到分隔符之前的字符串首地址,”hello’',然后在循环中继续调用strtok函数,第一个参数传NULL,strtok自己维护的静态变量,记住上次分隔的地方,不用在传arr1.

代码实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello@qq.com";
	char arr2[] = "@.";
	char* p =NULL;
	for (p = strtok(arr1, arr2); p != NULL; p = strtok(NULL, arr2))
	{
		printf("%s\n",p);
	}


}

编译运行
在这里插入图片描述


错误信息报告

strerror

功能:可以返回指向错误信息字符串地址
声明:char *strerror( int errnum );
头文件:string.h errno.h
参数:errnum是错误码,就像404页面,每个错误码对应着错误信息,返回值是指向错误信息字符串地址

int main()
{
	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));


}

在这里插入图片描述

当我们向内存申请空间时,我们会使用malloc函数,如果申请的内存太大,是否会报错呢??它会将错误码放在整型全局变量errno中,使用errno时引用头文件errno.h

代码展示:

`#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	  int *p=malloc(4000000000);//malloc申请内存失败会返回空地址
	  if (p == NULL)
	  {
		  printf("%s\n", strerror(errno));
	  }

}`

在这里插入图片描述

注意:遇到多个错误时,errno会不断赋新的错误码


模拟实现

strcat的模拟实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* mystrcat(char* p, char* q)
{
	assert(p && q);
	char* k = &p;//随着p++,会丢失目标字符串首地址先保存
	while (*p)
	{
		p++;
	}//将p指针移动到目标字符串'\0'位置
	while ((*p++=*q++))//将*q的值先给*p,然后两个q++;p++;赋值后的ascll值不为0,继续循环,当*q=='\0',赋值后ascll码值为'\0',退出循环
	{
	}
	return k;//返回目标字符串首地址
}
int main()
{
	char arr1[20] = "abcde";
	char arr2[5] = "qqq";
	mystrcat(arr1, arr2);
	printf("%s", arr1);

}

在这里插入图片描述


strstr的模拟实现

char* mystrstr(char* str1, char* str2)
{
	char* s1 = str1;//两个遍历指针分别指向两个字符串的首地址
	char* s2 = str2;
	char* cur = s1;//两个字符串开始匹配的指针
	while (*cur)//每循环一次,就是重新匹配的过程
	{
		s1 = cur;//s1移动到下一个开始匹配的位置
		s2 = str2;//子串要从头开始匹配
		while (*s1&&*s2&&(*s1 == *s2))//匹配的循环
		{
			s1++;
			s2++;
        }
		                            //不匹配退出循环
		if (*s2 == '\0')//当匹配循环完,s2的指针指向子串的末尾'\0';
		{
			return cur;//保存的是匹配成功时,字符串中匹配到的第一个字符首地址
		}
		cur++;                       //此时cur指向的位置不能作为开始匹配的位置,cur++;开始新一轮的匹配

    }
	return NULL;//当cur遍历完字符串,则说明没有该子串
}
int main()
{
	char arr1[] = "abcdecdfg";
	char arr2[] = "cdf";
	char *p=mystrstr(arr1,arr2);//如果找到子串返回字符串中和子串匹配的首字符首地址不为空
	if (p)
	{
		printf("是子串");
	}
	else
	{
		printf("不是子串");
	}

}

编译运行
在这里插入图片描述
在这里插入图片描述


总结

字符串函数,字符函数在处理字符问题特别的方便,使得问题简单化,本章还未讲到的内存操作函数放在下一篇讲,如果你觉得这篇文章对你有帮助的话,别忘了给小张点赞,收藏加关注,哪里不对的话还望大佬们指教,谢谢大家!!我会持续分享给大家自己学到的知识,也是在好好的做总结

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

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

相关文章

Git多版本并行开发实践

本文目的&#xff1a; 实现多个项目同时进行的git多版本管理工作流。 名词解释&#xff1a; feature-XXXX&#xff1a;特性分支指CCS中一个项目或者一个迭代&#xff0c;在该分支上开发&#xff0c;完成后&#xff0c;合并&#xff0c;最后&#xff0c;删除该分支&#xff0c;…

数据结构,线性表,顺序表基础。

1.线性表 线性表特征&#xff1a; 对非空表&#xff0c;a0是表头&#xff0c;无前驱a(n-1)是表尾&#xff0c;无后继其他的都有ai前驱a(i-1)与后继a(i1)。 2、顺序结构存储方式是线性表存储的一种方式&#xff0c;主要体现形式为数组。 #include<stdio.h> #include<st…

二、SQL,如何实现表的创建和查询

1、新建表格&#xff08;在当前数据库中新建一个表格&#xff09;&#xff1a; &#xff08;1&#xff09;基础语法&#xff1a; create table [表名]( [字段:列标签] [该列数据类型] comment [字段注释], [字段:列标签] [该列数据类型] comment [字段注释], ……&#xff0c…

2020年3月全国计算机等级考试真题(C语言二级)

2020年3月全国计算机等级考试真题&#xff08;C语言二级&#xff09; 第1题 有以下程序 void fun1 (char*p) { char*q; qp; while(*q!\0) { (*Q); q&#xff1b; } } main() { char a[]{"Program"},*p; p&a[3]; fun1(p); print…

由浅入深详解四种分布式锁

在多线程环境下&#xff0c;为了保证数据的线程安全&#xff0c;锁保证同一时刻&#xff0c;只有一个可以访问和更新共享数据。在单机系统我们可以使用synchronized锁或者Lock锁保证线程安全。synchronized锁是Java提供的一种内置锁&#xff0c;在单个JVM进程中提供线程之间的锁…

Hyper-v导致Vmware window无法启动崩溃记录

最近有几次vmware启动window10直接崩溃情况&#xff0c;显示蓝屏报错。一开始没在意&#xff0c;以为是因为固态硬盘错了几个字节导致的&#xff1f; 但后来想想不对啊。vmware用了也有10来年了&#xff0c;稳得一笔&#xff0c;在仔细思考了一下后发现打不开的win10这三个虚拟…

go_并发编程(1)

go并发编程 一、 并发介绍1&#xff0c;进程和线程2&#xff0c;并发和并行3&#xff0c;协程和线程4&#xff0c;goroutine 二、 Goroutine1&#xff0c;使用goroutine1&#xff09;启动单个goroutine2&#xff09;启动多个goroutine 2&#xff0c;goroutine与线程3&#xff0…

使用PDF文件入侵任何操作系统

提示&#xff1a;我们8月28号开学,所以我得快点更新了&#xff0c;不能拖了&#x1f625; 文章目录 前言一、打开终端总结 前言 PDF文件被广泛应用于共享信息&#xff0c;电子邮件&#xff0c;网站或文档或存储系统的真实链接 它可以用于恶意软件的载体。 不要问我什么意思&am…

【克罗恩病是银屑病及银屑病关节炎的因果风险因素】

克罗恩病是银屑病及银屑病关节炎的因果风险因素 ①纳入463372名欧洲人&#xff0c;包括12882例IBD患者、5621例银屑病患者、2063例银屑病关节炎患者&#xff1b;②单变量孟德尔随机化&#xff08;MR&#xff09;分析表明&#xff0c;基于遗传因素预测的IBD与较高的银屑病和银屑…

LangChain源码逐行解密之系统(二)

LangChain源码逐行解密之系统 20.2 serapi.py源码逐行剖析 我们可以看一下Google查询的例子,在LangChain中有多种实现的方式。 如图20-5所示,在utilities的serpapi.py代码文件中实现了SerpAPIWrapper。 图20- 5 utilities的serpapi.py的SerpAPIWrapper 在langchain目录的se…

力扣:64. 最小路径和(Python3)

题目&#xff1a; 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a…

dll修复精灵怎么下载,vcruntime140.dll丢失该如何修复

vcruntime140.dll是Microsoft Visual C Redistributable中的一个动态链接库&#xff08;DLL&#xff09;文件。它是一种运行时库&#xff08;Runtime Library&#xff09;&#xff0c;用于支持使用Microsoft Visual C编写的程序的正常运行。作为一个DLL文件&#xff0c;vcrunti…

进行 200 瓦太阳能 (PV) 模块设计以测量太阳能光伏阵列的电压、电流和功率、综合负荷频率和电压控制系统的方法研究(Simulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Ceph如何操作底层对象数据

1.基本原理介绍 1.1 ceph中的对象(object) 在Ceph存储中&#xff0c;一切数据最终都会以对象(Object)的形式存储在硬盘&#xff08;OSD&#xff09;上&#xff0c;每个的Object默认大小为4M。 通过rados命令&#xff0c;可以查看一个存储池中的所有object信息&#xff0c;例如…

使用 PyTorch 进行高效图像分割:第 2 部分

一、说明 这是由 4 部分组成的系列的第二部分&#xff0c;旨在使用 PyTorch 中的深度学习技术从头开始逐步实现图像分割。本部分将重点介绍如何实现基线图像分割卷积神经网络&#xff08;CNN&#xff09;模型。 图 1&#xff1a;使用 CNN 运行图像分割的结果。按从上到下的顺序…

【无标题】QT应用编程: QtCreator配置Git版本控制(码云)

QT应用编程: QtCreator配置Git版本控制(码云) 感谢&#xff1a;DS小龙哥的文章&#xff0c;这篇主要参考小龙哥的内容。 https://cloud.tencent.com/developer/article/1930531?areaSource102001.15&traceIdW2mKALltGu5f8-HOI8fsN Qt Creater 自带了git支持。但是一直没…

Github下载任意版本的VsCode

下载历史版本VsCode(zip) 下载链接由三部分组成&#xff1a; 固定部分commit idVSCode-win32-x64-版本号.zip 固定部分&#xff1a; https://vscode.cdn.azure.cn/stable/ Commit id&#xff1a; 打开 vscode的GitHub&#xff1a;[https://github.com/microsoft/vscode/r…

echarts 柱状图-折线图-饼图的基础使用

上图示例图表展示相关配置&#xff1a; var myChart echarts.init(this.$refs.firstMain);myChart.setOption({legend: { // 图例设置top: "15%",type: "scroll",orient: "vertical",//图例列表的布局朝向。left: "right",pageIconCo…

记录一个编译TubeTK时的报错:at_check问题

在使用如下命令安装TubeTK的cuda_nms时&#xff0c;报了一个错误&#xff0c;记录一下这个错误和解决办法 (base) redmeryredmery:~/Desktop/MOT/TubeTK/post_processing/nms$ python setup.py build_ext --inplace因为这个命令是在/home/redmery/Desktop/MOT/TubeTK/install/…

泛微 E-Office文件上传漏洞复现

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 文章作者拥有对此文章的修改和解释权。如欲转载或传播此文章&#xff0c…