c语言进阶(4)——字符函数的详细解析

news2025/1/15 20:35:03

文章目录

  • 1.strlen函数
  • 2.strcpy函数
  • 3.strcat函数
  • 4.strcmp函数
  • 5.strncpy函数
  • 6.strncat函数
  • 7.strncmp函数
  • 8.strstr函数
  • 9.strtok函数
  • 10. strerror函数
  • 11. 相关字符转换函数
  • 12.字符转换函数

1.strlen函数

size_t strlen( const char *string );

用途:用来计算字符串长度的。
要点:
(1)字符串已经有’\0’作为结束的表示符,strlen函数返回的是在字符串‘\0’之前的字符个数(不包括’\0’)。
(2)参数指向的字符串必须以‘/0’结尾。
(3)注意函数的返回值是size_t,是无符号的,所以(strlen函数返回的值相减一直都是大于等于0的)

c语言库的专业strlen实现

size_t __cdecl strlen (
        const char * str
        )
{
        const char *eos = str;

        while( *eos++ ) ;

        return( eos - str - 1 );
}

模拟实现strlen函数

//循环的思想
#include<assert.h>
size_t my_strlen1(const char* string)
{
	assert(string);
	int count = 0;
	while (*string)
	{
		count++;
		string++;
	}
	return count;
}

//指针减指针
size_t my_strlen2(const char* string)
{
	assert(string);
	const char* q = string;
	while (*q++)
	{
		;
	}
	return q - string;
}

//函数递归
size_t my_strlen3(const char* string)
{
	assert(string);
	if (*string == '\0')
		return 0;
	else
		return 1 + my_strlen3(string - 1);
}

2.strcpy函数

char* strcpy(char * destination, const char * source );

用途:将复制一个字符串到另一个字符数组里面。
要点:
(1)源字符串需要有‘/0’字符结尾。
(2)会将源字符串的‘/0’拷贝到目标空间。
(3)目标空间足够大,以确保能存放源字符串。
(4)目标空间需要可变。
C语言库专业的strcpy函数的实现

char * __cdecl strcpy(char * dst, const char * src)
{
        char * cp = dst;

        while((*cp++ = *src++) != '\0')
                ;               /* Copy src over dst */

        return( dst );
}

strcpy函数的模拟实现

#include<assert.h>
char* my_strcpy(char* dst, const char* src)
{
	assert(dst && src);
	char ret = dst;
	while (*dst++ = *src++)
	{
		;
	}
	return ret;
}

3.strcat函数

char * strcat ( char * destination, const char * source );

用途:将源字符串接到目标空间字符串的后面。
要点:
(1)源字符串必须以 ‘\0’ 结束。
(2)目标空间足够大,能容的下要接的字符串。
(3)目标空间必须可修改。
(4)不能自己给自己追加,会造成死循环。

C语言库专业实现strcat函数

char * __cdecl strcat (
        char * dst,
        const char * src
        )
{
        char * cp = dst;

        while( *cp )
                cp++;                   /* find end of dst */

        while((*cp++ = *src++) != '\0') ;       /* Copy src to end of dst */

        return( dst );                  /* return dst */

}

模拟实现strcat函数

char* my_strcat(char* destination, const char* source)
{
	assert(destination && source);
	char* ret = destination;
	//找到目标空间‘/0’的位置
	while (destination++)
	{
		;
	}
	//开始接
	while (*destination++ = *source++)
	{
		;
	}
	return ret;
}

4.strcmp函数

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

用途:比较两个函数之间的大小,按照字符来比较。
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字。
C语言库专业实现strcmp函数

int __cdecl strcmp (
        const char * src,
        const char * dst
        )
{
        int ret = 0 ;

        while((ret = *(unsigned char *)src - *(unsigned char *)dst) == 0 && *dst)
                {
                ++src, ++dst;
                }

        return ((-ret) < 0) - (ret < 0); // (if positive) - (if negative) generates branchless code
}

strcmp函数的模拟实现

int strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (*str1 - *str2 > 0)
	{
		return 1;
	}
	else
		return -1;
}

5.strncpy函数

char * strncpy ( char * destination, const char * source, size_t num );

用途:指定num个源字符串拷贝到目标空间。
要点:
(1)拷贝num个字符从源字符串到目标空间。
(2)如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
C语言库专业实现strncpy函数

char * __cdecl strncpy (
        char * dest,
        const char * source,
        size_t count
        )
{
        char *start = dest;

        while (count && (*dest++ = *source++) != '\0')    /* copy string */
                count--;

        if (count)                              /* pad out with zeroes */
                while (--count)
                        *dest++ = '\0';

        return(start);
}

模拟实现strncpy函数

char* strncpy(char* destination, const char* source, size_t num)
{
	assert(destination && source);
	char* ret = destination;
	while (*source && num)
	{
		*destination = *source;
		destination++;
		source++;
		num--;
	}
	if (num)
	{
		while (num)
		{
			*destination = '\0';
			num--;
		}
	}
	else
	{
		*destination = '\0';
	}
	return ret;
}

6.strncat函数

char * strncat ( char * destination, const char * source, size_t num );

用途:指定num个字符从源字符串中接到目标空间处。
C语言库专业实现strncat函数

char * __cdecl strncat (
        char * front,
        const char * back,
        size_t count
        )
{
        char *start = front;

        while (*front++)
                ;
        front--;

        while (count--)
                if ((*front++ = *back++) == 0)
                        return(start);

        *front = '\0';
        return(start);
}

模拟实现strncat函数

char* strncat(char* destination, const char* source, size_t num)
{
	assert(destination && source);
	char* ret = destination;
	while (num)
	{
		if ((*destination++ = *source++) == 0)
			return ret;
		num--;
	}
	*destination = '\0';
	return ret;
}

7.strncmp函数

int strncmp ( const char * str1, const char * str2, size_t num );

用途:比较num个字符。

模拟实现strncmp函数

int strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	while (*str1 == *str2&&num--)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (!num)
	{
		return 0;
	}
	if (*str1 - *str2 > 0)
	{
		return 1;
	}
	else
		return -1;
}

8.strstr函数

char * strstr ( const char *str1, const char * str2);

用途:判断在str1中是否有str2的字符串。
要点:
(1)在str1找的第一个str2字符串的位置,直接返回该位置。
(2)未找到的话,返回的是NULL。

char * __cdecl strstr (
        const char * str1,
        const char * str2
        )
{
        char *cp = (char *) str1;
        char *s1, *s2;

        if ( !*str2 )
            return((char *)str1);

        while (*cp)
        {
                s1 = cp;
                s2 = (char *) str2;

                while ( *s2 && !(*s1-*s2) )
                        s1++, s2++;

                if (!*s2)
                        return(cp);

                cp++;
        }

        return(NULL);

}

模拟实现strstr函数

char* strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cp = str1;
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 == *s2&&*s1!='\0'&&*s2!='\0')
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cp;
		}
		cp++;
	}
	return NULL;
}

9.strtok函数

char * strtok ( char * str, const char * sep );

用途:将特定的字符串,以若干个分割符隔开。
要点:
(1)sep参数是个字符串,定义了用作分隔符的字符集合;
(2)第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
(3)strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
(4)strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
(5)strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
(6)如果字符串中不存在更多的标记,则返回 NULL 指针。

使用方法:以循环的形式实现。

int main()
{
	//char arr[] = "zpengwei@yeah.net";//"@."
	char arr[] = "192#168.120.85";
	char* p = "#.";
	char buf[20] = { 0 };//"zpengwei\0yeah\0net"
	strcpy(buf, arr);
	char* ret = NULL;
	for (ret = strtok(buf, p); ret != NULL; ret=strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	
	//char* ret = strtok(buf, p);
	//printf("%s\n", ret);
	//ret = strtok(NULL, p);
	//printf("%s\n", ret);
	//ret = strtok(NULL, p);
	//printf("%s\n", ret);

	//zpengwei
	//yeah
	//net
	return 0;
}

10. strerror函数

char * strerror ( int errnum );

用途:返回错误码,指出错误的信息。

/* strerror example : error list */
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main ()
{
 FILE * pFile;
 pFile = fopen ("unexist.ent","r");
 if (pFile == NULL)
  printf ("Error opening file unexist.ent: %s\n",strerror(errno));
  //errno: Last error number
 return 0;
}

注释:参数是整数,代表的是错误类型的编码;此时errno代表的是此时错误的整数。

11. 相关字符转换函数

在这里插入图片描述
是的话返回大于零的整数,不是的话返回0;

12.字符转换函数

int tolower ( int c );//小写
int toupper ( int c );//大写

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云原生进阶之容器】第二章Controller Manager原理2.8节--Resync机制

8 Resync机制 8.1 DeltaFIFO队列为什么需要Resync 为什么需要 Resync 机制呢?因为在处理 SharedInformer 事件回调时,可能存在处理失败的情况,定时的 Resync 让这些处理失败的事件有了重新 onUpdate 处理的机会。 主要的目的是为了不丢数据,处理 resync 机制还有边缘触发与…

公务员考试催生一家上市公司,公务员真的是一条好的出路吗

公务员考试能催生一家公司吗&#xff1f;还真的可以&#xff0c;而且在2023.01.09日也就是今天上市。公务员真的是一条好的出路吗&#xff0c;现在考公务员还行不行&#xff1f;这需要结合我们当下的环境来综合分析。我们都经历了疫情&#xff0c;期间各个大厂频频将裁员大棒挥…

《Spring揭秘》读书笔记 1:IoC和AOP

1 Spring框架的由来 Spring框架的本质&#xff1a;提供各种服务&#xff0c;以帮助我们简化基于POJO的Java应用程序开发。 各种服务实现被划分到了多个相互独立却又相互依赖的模块当中&#xff1a; Core核心模块&#xff1a;IoC容器、Framework工具类。 AOP模块&#xff1a;S…

如何抓住风口,利用互联网赚钱?(內含三大商业模式推荐)建议收藏

大家好&#xff0c;我是你们熟悉而又陌生的好朋友梦龙&#xff0c;一个创业期的年轻人 今天跟你做个分享&#xff0c;众所周知互联网是一块非常大的蛋糕&#xff0c;几位互联网巨头也做不到完全吃透&#xff0c;同时也是一个门槛较低的创业之路&#xff0c;非常的适合年轻人&a…

8、Javaweb_ServlethttpRequst

Servlet&#xff1a; 1. 概念 2. 步骤 3. 执行原理 4. 生命周期 5. Servlet3.0 注解配置 6. Servlet的体系结构 Servlet -- 接口 | GenericServlet -- 抽象类 | HttpServlet -- 抽象类 * GenericServlet&#xff1a;将Servlet接口中其他的方…

C语言-指针进阶-常见笔试面试题详解(9.4)

目录 思维导图&#xff1a; 指针和数组笔试题 指针笔试题 写在最后&#xff1a; 思维导图&#xff1a; 指针和数组笔试题 只有多刷题&#xff0c;才能巩固提高所学的知识。 例1&#xff1a; #include <stdio.h>int main() {//一维数组int a[] { 1,2,3,4 };//求出…

「精研科技」× 企企通,全球MIM龙头借助采购供应商数字化向多领域突破

近日&#xff0c;金属粉末注射成型&#xff08;MIM&#xff09;龙头企业江苏精研科技股份有限公司&#xff08;以下简称“精研科技”&#xff09;与企企通达成合作。双方将共同构建完整的采购管理和供应商协同平台&#xff0c;加强供应商管理&#xff0c;提高采购效率&#xff…

Netty源码性能分析 - ThreadLocal PK FastThreadLocal

序 既然jdk已经有ThreadLocal&#xff0c;为何netty还要自己造个FastThreadLocal&#xff1f;FastThreadLocal快在哪里&#xff1f;这需要从jdk ThreadLocal的本身说起。在java线程中&#xff0c;每个线程都有一个ThreadLocalMap实例变量&#xff08;如果不使用ThreadLocal&…

使用Alexnet实现CIFAR100数据集的训练

如果对你有用的话&#xff0c;希望能够点赞支持一下&#xff0c;这样我就能有更多的动力更新更多的学习笔记了。&#x1f604;&#x1f604; 使用Alexnet进行CIFAR-10数据集进行测试&#xff0c;这里使用的是将CIFAR-10数据集的分辨率扩大到224X224&#xff0c;因为在测试…

【ROS】—— ROS常用组件_TF坐标变换_多态坐标变换与TF坐标变换实操(十一)

文章目录前言1. 多态坐标变换1.1 发布方1.2 订阅方(C)1.3 订阅方(python)2. 坐标系关系查看3. TF坐标变换实操(C)3.1准备3.2 生成新的乌龟3.3 增加键盘控制3.4 发布方(发布两只乌龟的坐标信息)3.5 订阅方(解析坐标信息并生成速度信息)前言 &#x1f4e2;本系列将依托赵虚左老师…

将git仓库瘦身

一个小工具的仓库居然有7个g了&#xff0c;每次clone都要等好久&#xff0c;在网上找的方法&#xff0c;实际了几个小时才成功瘦身&#xff0c;做一次记录 一、排查是哪些历史文件占用了内存&#xff0c;下面是查询最大的5个文件 git rev-list --objects --all | grep "$(…

使用nvm管理node版本,实现高版本与低版本node之间的转换

第一步&#xff1a;先清空本地安装的node.js版本 1.按健winR弹出窗口&#xff0c;键盘输入cmd,然后敲回车&#xff08;或者鼠标直接点击电脑桌面最左下角的win窗口图标弹出&#xff0c;输入cmd再点击回车键&#xff09; 然后进入命令控制行窗口&#xff0c;并输入where node查…

Linux环境配置

一、安装ubuntu16的步骤 1、新建Ubuntu 右击文件---------新建虚拟机 典型----------------下一步 稍后安装操作系统-------------下一步 Linux&#xff08;L&#xff09;------------------Ubuntu64位-----------------下一步 虚拟机名称&#xff08;随意起&#xff09;----…

OSS简单介绍

OSS 阿里云对象存储OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;可提供99.9999999999%&#xff08;12个9&#xff09;的数据持久性&#xff0c;99.995%的数据可用性。多种存储类型供选择&#xff0c;全面优化…

197: vue+openlayers 预加载preload瓦片地图,减少过渡期间的空白区域

第197个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中演示瓦片预加载和没有预加载的不同状态。 没有采用预加载 当我们平移和缩放地图时,经常会遇到过渡期间的空白区域(因为内容正在加载),过一会儿,切片图像才出现了。 采用预加载,将预载的值设置为…

深入ReentrantLock锁

1. 前言 今天我们来探讨下另一个核心锁ReentrantLock. 从具体的实现到JVM层面是如何实现的。 我们都会一一进行讨论的&#xff0c;好了&#xff0c;废话不多说了&#xff0c;我们就开始吧 2. ReentrantLock 以及synchronized 核心区别&#xff1a; ReentrantLock 是一个抽象的…

MVC框架知识详解

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

机器学习课程学习随笔

文章目录本文来源机器学习简介机器学习流程机器学习可以完成如下功能&#xff1a;机器学习应用场景金融领域零售领域机器学习分类机器学习实现基于python等代码自己实现本文来源 本博客 是通过学习亚马逊的官方机器学习课程的随笔。 课程参考链接https://edu.csdn.net/course/…

爬虫与反爬虫 - 道高一尺魔高一丈 - 2013最新 - JS逆向 - Python Scrapy实现 - 爬取某天气网站历史数据

目录 背景介绍 网站分析 第1步&#xff1a;找到网页源代码 第2步&#xff1a;分析网页源代码 Python 实现 成果展示 后续 Todo 背景介绍 今天这篇文章&#xff0c;3个目的&#xff0c;1个是自己记录&#xff0c;1个是给大家分享&#xff0c;还有1个是向这个被爬网站的前…

synchronized锁膨胀(附代码分析)

synchronized锁膨胀 1. 基本概念 Java对象头 Java对象的对象头信息中的 Mark Word 主要是用来记录对象的锁信息的。 现在看一下 Mark Word 的对象头信息。如下&#xff1a; 其实可以根据 mark word 的后3位就可以判断出当前的锁是属于哪一种锁。注意&#xff1a;表格中的…