#include<string.h>常用函数(C语言)

#include<string.h> 是C语言中的一个常用的头文件,其定义了许多关于字符串操作的函数和一些其它函数,如:strlen、strcpy、strcap、memcpy、memmove等。

文章目录

  • 1、求字符串长度:strlen
    • strlen的使用
    • strlen模拟实现
  • 2、拷贝函数:strcpy、strncpy
    • strcpy的使用
    • strcpy的模拟实现
    • strncpy的使用
  • 3、追加函数:strcat、strncat
    • strcat的使用
    • strcat的模拟实现
    • strncat的使用
  • 4、比较两个字符串的大小:strcmp 、strncmp
    • strcmp的使用
    • strcmp的模拟实现
    • strncmp的使用
  • 5、字符串查找函数:strstr
    • strstr的使用
    • strstr的模拟实现
  • 6、分割字符串函数:strtok
    • strtok的使用
  • 7、错误信息报告函数:strerror
    • 举例使用
  • 8、内存操作函数:memcpy、memmove、memset、memcmp
    • (1)memcpy内存拷贝函数
      • memcpy的使用:
      • memcpy的模拟实现
    • (2)memmove内存拷贝函数
      • memmove的使用
      • memmove的模拟实现
    • (3)memset内存设置函数
      • memset的使用
    • (4)memcmp内存比较函数
      • memcmp的使用
  • 9、字符分类函数
    • 举例使用
  • 10、转换大小写
    • 举例使用

1、求字符串长度:strlen

size_t strlen( const char* string );
作用:求字符串的长度。
注意:

1.注意函数的返回值为size_t,是无符号的。
2. strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
3. 参数指向的字符串必须要以 ‘\0’ 结束。

strlen的使用

strlen模拟实现

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

int my_strlen(const char* str)
{
	int count = 0;
	assert(str != NULL);//进行断言,不为空,为空会报警告
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char ch[] = "abcdef";
	int n = my_strlen(ch);
	printf("%d\n", n);
	return 0;
}

2、拷贝函数:strcpy、strncpy

char *strcpy( char*strDestination, const char*strSource);
**作用:**将一个字符串的内容拷贝到另一个字符串内
注意:

  1. 源字符串必须以 ‘\0’ 结束。
  2. 会将源字符串中的 ‘\0’ 拷贝到目标空间。
  3. 目标空间必须足够大,以确保能存放源字符串。
  4. 目标空间必须可变。 如:将ch2拷贝到ch1中,若char*ch1=“abcdefghi”; 则会崩溃,因为ch1是指向的是常量字符串,若将ch2拷贝到ch1会崩溃。
  5. 只能拷贝字符串,若要拷贝 int ch1[ ]={1,2,3,4,5} 放在 int ch2[100]={ 0 } 中,则不行 若要拷贝,则应使用 memcpy函数。

strcpy的使用

strcpy的模拟实现

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

char* my_strcpy(char* str1, const char* str2)
{
    assert(str1 != NULL);
	assert(str2 != NULL);
	char* ret = *str1;
	while (*str2 != '\0')
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = '\0';
	return ret;
}
int main()
{
	char ch1[10] = "abcdefgh";
	char ch2[] = "xxxxxx";
	my_strcpy(ch1, ch2);1
	printf("%s\n", ch1);
	return 0;
}

strncpy的使用

char*strncpy( char*strDest, const char*strSource, size_t count );
size_t count 意思是比较前count个字符

3、追加函数:strcat、strncat

char* strcat( char*strDestination, const char*strSource );
作用:将一个字符串的内容追加到另一个字符串的后面
注意:

  1. 源字符串必须以 ‘\0’ 结束。 如:ch2={‘b’,‘i’,‘t’}则会崩溃
  2. 目标空间必须有足够的大,能容纳下源字符串的内容。如:char ch1[ ]=“abcdef” 将ch2追加到ch1会崩溃 ,应为char ch1[100]=“abcdef”
  3. 目标空间必须可修改。

strcat的使用

strcat的模拟实现

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

char* my_strcat(char* str1, const char* str2)
{
    assert(str1 != NULL);
	assert(str2 != NULL);
	char* ret = str1;
	while (*str1 != '\0')
	{
		str1++;
	}
	while (*str2 != '\0')
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = '\0';
	return ret;
}
int main()
{
	char ch1[100] = "abcdefgh";
	char ch2[] = "xxxxxx";
	my_strcat(ch1, ch2);//将ch2的内容追加到ch1后面
	printf("%s\n", ch1);
	return 0;
}

strncat的使用

int strncmp( const char*string1, const char*string2, size_t count );
size_t count 意思是比较前count个字符

4、比较两个字符串的大小:strcmp 、strncmp

int strcmp( const char*string1, const char*string2 );
作用:比较两个字符串的大小。
使用方法:通过函数的返回值来比较大小。

第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

字符串的比较原理

比较ASCII码值(如比较ch1[ ]=“aqwer”;与ch2[ ]=“abwer”😉
若ch1[]为”aqwer”则先a与a比较,相等,再比较b与q,b<q,所以p2>p1
若ch2[ ]为”abwer”,原理同上。

strcmp的使用

strcmp的模拟实现

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

int my_strcmp(const char* str1, const char* str2)
{
    assert(str1 != NULL);
	assert(str2 != NULL);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
		return 1;
	else
		return -1;
}
int main()
{
	char ch1[] = "aqwer";
	char ch2[] = "abwer";
	int n = my_strcmp(ch1, ch2);
	if (n > 0)
		printf("ch1大于ch2\n");
	else if (n == 0)
		printf("ch1等于ch2\n");
	else
		printf("ch1小于ch2\n");
	return 0;
}

strncmp的使用

int strncmp( const char*string1, const char*string2, size_t count );
size_t count 意思是比较前count个字符。

5、字符串查找函数:strstr

char*strstr( const char*string, const char*strCharSet );
作用:找子串( 在字符串1中找是否包含字符串2,找到了返回字符串1中与字符串2首元素相同的元素的地址,若未找到则返回值为空 )

strstr的使用

strstr的模拟实现

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

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 != NULL);//确保str1不为空指针
	assert(str2 != NULL);//确保str2不为空指针
	while (*str1 != '\0')
	{

		char* ret = str1;
		char* p1 = str1;
		char* p2 = str2;
		while ((*p1 == *p2)&&(*p1!='\0')&&(*p2!='\0'))
		{
			p1++;
			p2++;
		}
		if (*p2 == '\0')
		{
			return ret;
		}
		if (*p1 == '\0')
		{
			return NULL;
		}
		str1++;
	}
	return NULL;
}

int main()
{
	char ch1[] = "abcdefghijklmn";
	char ch2[] = "lmn";
	char* ret = my_strstr(ch1, ch2);
	if (ret != NULL)
		printf("找到了\n");
	else
		printf("未找到\n");
	return 0;
}

6、分割字符串函数:strtok

char*strtok( char*strToken, const char*strDelimit );
作用:将字符串进行分割,如ch1[ ]=“312456781425@qq.com”; 与 ch2[ ]=“@.”; 可以将其分割为312456781425 与 qq 与 com
strtok原理(strtok具有记忆功能):

1、strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
2、strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 如果字符串中不存在更多的标记,则返回NULL 指针。

举例:在ch1中”312456781425@qq.com”找ch2中所包含的元素:

  1. char* ret = strtok(ch1, ch2); 当找到 @ 时,将 @ 替换成’\0’,打印printf(“%s\n”, ret)时到’\0’停止,相当于只打印312456781425
  2. 此时strtok会保存被替换成’\0’的 @ 的地址,下一个打印时只要将ch1替换成NULL,再找一个接收
  3. 此时写为ret = strtok(NULL, ch2),再打印printf(“%s\n”, ret),会打印qq
  4. 接下来同理打印出com

strtok的使用

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

int main()
{
	char ch1[] = "312456781425@qq.com";
	char ch2[] = "@."; 
	char* ret = NULL;
	for (ret = strtok(ch1, ch2); ret != NULL; ret = strtok(NULL, ch2))
	{
		printf("%s\n", ret); 
	}
	return 0;
} 

7、错误信息报告函数:strerror

char*strerror( int errnum );
以下是VS2022中的错误码与错误信息

错误码错误信息
0No error
1Operation not permitted
2No such file or directory
3No such process
. . . . . .

错误码变量errno:errno 是一个全局的错误码变量,当c语言的库函数在执行过程中发生了错误,就会把对应的错误码赋值到errno中。
作用:通过错误码报告错误信息。
打印错误码中的错误信息:

举例使用

打开文件失败返回错误码

8、内存操作函数:memcpy、memmove、memset、memcmp

以上函数都是与字符串相关,但如果涉及到int、double、float则无法使用,而内存拷贝函数可以进行相关操作。

(1)memcpy内存拷贝函数

作用:进行内存拷贝,与strcpy类似
void*memcpy( void*dest, const void*src, size_t count );
:size_t是无符号整形unsigned(size_t count是指以字节为单位拷贝)

memcpy的使用:

memcpy的模拟实现

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

void* my_memcpy(void* str1, const void* str2, size_t count)
{
    assert(str1 != NULL);
	assert(str2 != NULL);
	char* ret = str1;
	while (count--)
	{
		*(char*)str1 = *(char*)str2;
		str1 = (char*)str1 + 1;
		str2 = (char*)str2 + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 1,1,1,1,1,1 };
	my_memcpy(arr1, arr2, 24);
	//将arr2中的内容拷贝到arr1中,24的意思是24个字节,即4*6=24
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
	return 0;
}

:memcpy不能自己拷贝自己,如:memcpy( arr1+2, arr2, 20 ),会出现内存重叠。若要自己拷贝自己,应使用memmove函数。

(2)memmove内存拷贝函数

void*memmove( void*dest, const void*src, size_t count );
(size_t count是指以字节为单位拷贝)
memmove函数与memcpy类似,都是进行内存拷贝,但功能比memcpy更强大(可以自己拷贝自己)

memmove的使用

memmove的模拟实现

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

void* my_memmove(void* str1, void* str2, size_t count)
{
    assert(str1 != NULL);
	assert(str2 != NULL);
	void* ret = str1;
	if (str1 < str2)
	{
		while (count--)
		{
			*(char*)str1 = *(char*)str2;
			++(char*)str1;
			++(char*)str2;
		}
	}
	else
	{
		while (count--)
		{
			*((char*)str1 + count) = *((char*)str2 + count);
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 1,1,1,1,1,1 };
	my_memmove(arr1+2, arr1, 24);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
	return 0;
}

(3)memset内存设置函数

void*memset( void*dest, int c, size_t count );
作用:进行内存设置(size_t count是指以字节为单位设置)。

memset的使用

(4)memcmp内存比较函数

int memcmp( const void*buf1, const void*buf2,s ize_t count );
作用:进行内存比较,与strcmp类似
使用方法:通过函数的返回值来比较大小。

第一个字节内容大于第二个字节内容,返回大于0的数字
第一个字节内容等于第二个字节内容,则返回0
第一个字节内容小于第二个字节内容,则返回小于0的数字

memcmp的使用

9、字符分类函数

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower小写字母a~z
isupper大写字母A~Z
isalpha字母az或AZ
isalnum字母或者数字,az,AZ,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

举例使用


其它自行尝试。

10、转换大小写

int tolower ( int c ); 将大写转换为小写
int toupper ( int c ); 将小写转换为大写

举例使用

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年12月21日
下一篇 2023年12月21日

相关推荐