C语言字符函数和字符串函数示例详解

 更新时间:2025年10月06日 08:54:26   作者:代码村新手  
C语言中有一系列的函数是对字符进行分类的,就是对判断一个字符属于什么类型的字符,这类字符函数的使用都要包含一个头文件ctype.h,这篇文章主要介绍了C语言字符函数和字符串函数的相关资料,需要的朋友可以参考下

一、函数介绍

1.1 strlen

求字符串长度函数

size_t strlen(const char* str)

参数和返回值介绍:

const char* str:要求长度的字符串

返回值:返回字符串的长度,类型为无符号整型

1.1.1 字符串以'\0'作为结束标志,strlen函数返回的是字符串中'\0'前面出现的字符个数(不包含'\0')。

1.1.2 指向的字符串必须包含'\0',否则可能会返回随机值。

1.1.3 返回的类型是size_t也就是无符号整型

strlen的简易模拟实现:

size_t my_strlen(const char* str)
{
	assert(str);
	size_t count = 0;
	while (*str++)
	{
		count++;
	}
	return count;
}

1.2 strcpy

字符串拷贝函数

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

参数和返回值介绍:

const char* source:源字符串

char* destination:目标空间

返回值:返回目标空间的地址

1.2.1 源字符串必须以'\0'结尾。

1.2.2 会将源字符串中的'\0'拷贝到目标空间中。

1.2.3 目标空间必须足够大,以确保能够存放源字符串。

1.2.4 目标空间必须可变,不能是常量字符串。

strcpy的简易模拟实现:

char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);
	char* tmp = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return tmp;
}

1.3 strcat

字符串追加函数

char* strcat(char* destinaion, const char* source)

参数和返回值介绍:

const char* source:源字符串

char* destination:目标空间

返回值:返回目标空间的地址

1.3.1 源字符串必须以'\0'结尾。

1.3.2 目标空间必须足够大,能够容纳下源字符串的内容。

1.3.3 目标空间必须可修改。

1.3.4 字符串不能自己给自己追加。

注:当自己给自己追加后src就会永远找不到'\0'的位置,从而停不下来了

strcat的简易模拟实现:

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* tmp = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return tmp;
}

1.4 strcmp

字符串比较函数

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

参数和返回值介绍:

str1和str2:要进行比较的两个字符串

返回值:当str1>str2时,返回一个大于0的数

               当str1<str2时,返回一个小于0的数

               当str1和str2相等时,返回0

strcmp的简易模拟实现:

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

1.5 strncpy

指定长度的字符串拷贝函数

char* strcpy(char* destination, const char* source, size_t num)

参数和返回值介绍:

const char* source:源字符串

char* destination:目标空间

size_t num:要拷贝的字符个数

返回值:返回目标空间的地址

1.5.1 拷贝num个字符从源字符串到目标空间。

1.5.2 如果源字符串长度小于num,在拷贝完源字符串后,在目标空间的后面追加0,直到num个。

当源字符串长度小于num时:

strncpy的简易模拟实现:

char* my_strncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* tmp = dest;
	int num1 = num;
	while (num1-- && (*dest++ = *src++))
	{
		;
	}
	if (num1>0)
	{
		while (num1--)
		{
			*dest++ = '\0';
		}
	}
	*dest = '\0';
	return tmp;
}

1.6 strncat

指定追加字符个数函数

char* strncat(char* destinaion, const char* source, size_t num)

参数和返回值介绍:

const char* source:源字符串

char* destination:目标空间

size_t num:要拷追加的字符个数

返回值:返回目标空间的地址

1.6.1 向目标空间追加n个属于源字符串的字符。

1.6.2 当源字符串长度小于n时,将不在追加,后面直接加一个'\0'。

strncat的简易模拟实现:

char* my_strncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* tmp = dest;
	while (*dest)
	{
		dest++;
	}
	while (num)
	{
		*dest++ = *src++;
		num--;
		if (*src == '\0')
		{
			break;
		}
	}
	*dest = '\0';
	return tmp;
}

1.7 strncmp

比较前n个字符的大小函数

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

参数和返回值介绍:

str1和str2:要进行比较的两个字符串

size_t num:要比较的字符个数

返回值:当str1>str2时,返回一个大于0的数

               当str1<str2时,返回一个小于0的数

               当str1和str2相等时,返回0

strncmp的简易模拟实现:

int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	while (num && (*str1 == *str2))
	{
		num--;
		str1++;
		str2++;
	}
	//只有num等于0时str1才会和str2的前num个字符相等
	//否则要么是num还没到0,*str1就和*str2不相等了
	if (num == 0)
	{
		return 0;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

1.8 strstr

字符串找子串函数

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

参数和返回值介绍:

str1和str2:在字符串str1中找到str2第一次出现的位置

返回值:找到了就返回str1第一次找到str2后的位置,找不到返回NULL

strstr的简易模拟实现:

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* ch = (char*)str1;
	char* s1 = NULL;
	char* s2 = NULL;
	//结束条件是ch为\0
	while (*ch)
	{
		s1 = ch;
		s2 = (char*)str2;
		while (*s1&&*s2&&(*s1 == *s2))
		{
			s1++;
			s2++;
		}
		//当s2为'\0'时就找到了子串
		if (*s2 == '\0')
		{
			return ch;
		}
		ch++;
	}
	return NULL;
}

1.9 strtok

分割字符串

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

参数和返回值介绍:

char* str:需要进行分割的字符串

const char* sep:分隔符

1.9.1 sep是一个字符串,定义了用作分隔符的字符合集。

1.9.2 第一个参数指定一个字符串,它包含0个或多个由sep字符串中一个或多个分隔符分割的标记。

1.9.3 strtok会找到str的下一个标记,并将其替换成\0,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝内容,并且可以被修改)

1.9.4 strtok第一个参数不为NULL,strtok函数将找到str中的第一个标记,strtok将保存它在字符串中的位置。

1.9.5 strtok第一个参数为NULL,strtok函数将在同一个字符串中被保存的位置开始,查找下一个标记。

1.9.6 如果字符串中不包含更多标记,将返回NULL。

使用方法:

char arr[] = "helloworld@yeah.net";
char sep[] = "@.";
char tmp[30];
strcpy(tmp, arr);
char* ret = strtok(arr, sep);		//第一次传参需要传字符串,最好传一个临时拷贝的字符串
printf("%s\n", ret);
ret = strtok(NULL, sep);			//除了第一次需要传字符串之外,剩下的只需要传NULL就行
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);

在不知道具体有多少分隔符时的使用方法:

char arr[] = "helloworld@yeah.net#yyy";
char sep[] = "@.#";
char tmp[30];
strcpy(tmp, arr);
char* ret = NULL;
for (ret = strtok(tmp, sep); ret != NULL;ret=strtok(NULL,sep))
{
	printf("%s\n", ret);
}

1.10 strerror

库函数在执行的时候如果发生了错误,会将一个错误码存放在errno这个变量中,errno是C语言提供的一个全局变量

提供错误码,输出错误码对应的错误信息

char* strerror(int errnum)

需要包含的头文件#include<errno.h>

使用方法:

perror相较于strerror来说能够更彻底的打印错误信息。

perror("fopen");

字符串分类函数

头文件:#include<ctype.h>

函数如果判断结果为真就返回一个非0的数,判断结果为假就返回0
iscntrl任意控制字符
isspace空格字符:空格' '、换页'\f'、换行'\n'、回车'\r'、制表符'\t'、垂直制表符'\v'
isdigit十进制数字0~9
isxdigit十六进制数字,包括所有十进制数字0~9,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或字母的可打印符号
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

字符转换:

int tolower(int c);		//将大写字母转换成小写字母
int toupper(int c);		//将小写字母转换成大写字母

1.11 memcpy

内存拷贝函数

void* memcpy(void* destaintion,const void* source,size_t num)

参数和返回值介绍:

void* destaintion:目的地

const void* source:源

size_t num:要拷贝的字节个数

返回值:返回目标空间的起始地址

1.11.1 memcpy从sourec的位置开始向后复制num个字节的数据到destaintion的内存位置。

1.11.2 这个函数并不关心'\0',在遇到'\0'时并不会停下来。

1.11.3 memcpy是专门用来处理不相关,不重叠的内存拷贝的,如果source和destination有任何的内容重叠了,那么结果是不可预测的。

1.11.4 source和destination的传参类型最好要保持一致,可以传不同类型的,但结果是不可预测的。

memcpy的简易模拟实现:

void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	while (num--)
	{
		*((char*)dest) = *((char*)src);
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

1.12 memmove

内存拷贝函数

void* memmove(void* destaintion,const void* source,size_t num)

参数和返回值介绍:

void* destaintion:目的地

const void* source:源

size_t num:要拷贝的字节个数

返回值:返回目标空间的起始地址

1.12.1 和memcpy的区别在于memmove能额外处理内容重叠的拷贝。

1.12.2 如果源空间和目标空间发生了重叠,就得使用memmove来处理。

memmove的使用场景:

memmove的简易模拟实现:

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)
	{
		//从前往后拷贝
		while (num--)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//从后往前拷贝
		while (num--)
		{
			*((char*)dest+num) = *((char*)src+num);
		}
	}
	return ret;
}

1.13 memcpy

内存比较函数

int memcmp(const void* ptr1,const void* ptr2,size_t num)

参数和返回值介绍:

ptr1和ptr2:要进行比较的两组内存中的数据

num:要比较的字节个数

返回值:ptr1>ptr2返回一个大于0的数字

              ptr1==ptr2返回0

              ptr1<ptr2返回一个小于0的数字

1.13.1 只比较前num个字节大小。

1.13.2 memset是一对字节一对字节依次进行比较的。

1.14 memset

内存设置函数

void* memset(void* ptr,int value,size_t num)

参数和返回值介绍:

ptr:要设置的内存空间

value:要设置的值

num:设置的字节个数

返回值:返回指向的内存空间

1.14.1 memset内存设置是以字节为单位设置的。

总结

到此这篇关于C语言字符函数和字符串函数的文章就介绍到这了,更多相关C语言字符函数和字符串函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++设计模式编程中Template Method模板方法模式的运用

    C++设计模式编程中Template Method模板方法模式的运用

    这篇文章主要介绍了C++设计模式编程中Template Method模板方法模式的运用,讲到了包括模板方法模式中的细分方法以及适用场景,需要的朋友可以参考下
    2016-03-03
  • C语言 struct结构体超详细讲解

    C语言 struct结构体超详细讲解

    C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型),下面这篇文章主要给大家介绍了关于C语言结构体(struct)的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • 基于C语言扫雷游戏的设计与实现

    基于C语言扫雷游戏的设计与实现

    大家好,本篇文章主要讲的是基于C语言扫雷游戏的设计与实现,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • getdate()函数的用法实例

    getdate()函数的用法实例

    getdate()函数的用法实例,需要的朋友可以参考一下
    2013-03-03
  • Qt实现指针式时钟 Qt实现动态时钟

    Qt实现指针式时钟 Qt实现动态时钟

    这篇文章主要为大家详细介绍了Qt实现指针式时钟,Qt实现动态时钟,两者相互切换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • C/C++内存管理详情

    C/C++内存管理详情

    这篇文章主要通过描述了C/C++内存分布、C/C++的一些函数理方面来展开C/C++内存管理的内容,需要的朋友请参考下文
    2021-08-08
  • C语言静态与动态通讯录的实现流程详解

    C语言静态与动态通讯录的实现流程详解

    这篇文章主要为大家介绍了C语言分别实现静态与动态的通讯录示例代码教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-11-11
  • C++简单实现的全排列算法示例

    C++简单实现的全排列算法示例

    这篇文章主要介绍了C++简单实现的全排列算法,结合实例形式分析了C++排序操作的实现技巧,需要的朋友可以参考下
    2017-07-07
  • C++学习笔记之浅谈异常处理

    C++学习笔记之浅谈异常处理

    C++ 提供了异常机制,让我们能够捕获运行时错误,本文就详细的介绍了C++异常处理入门,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 一文搞懂C++11万能引用和右值引用

    一文搞懂C++11万能引用和右值引用

    本文主要介绍了C++11万能引用和右值引用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论