IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 字符函数和字符串函数 -> 正文阅读

[游戏开发]字符函数和字符串函数

一、函数介绍

1、strlen

特点:

(1)、字符串的结束标志是‘\0’,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包
'\0' );
(2)、函数传参的内容是字符指针 char *,返回值是 size_t(无符号);
(3)、参数指向的字符串必须以‘\0’结束。
strlen函数的模拟实现
//计数器法
int my_strlen(const char* str)
{
	assert(str != NULL);
	int count = 0;
	while (*str++ != '\0')
	{
		count++;
	}
	return count;
}

//递归法
int my_strlen(const char* str)
{
	assert(str != NULL);
	if (*str != '\0')
	{
		return 1 + my_strlen(str + 1);
	}
	else
		return 0;
}

//指针-指针
int my_strlen(const char* str)
{
	assert(str != NULL);
	char* dest = str;
	while (*dest != '\0')
	{
		dest++;
	}
	return dest - str;
}

2、strcpy——字符串拷贝(返回目标空间的起始地址)

//使用演示
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	strcpy(arr1, arr2);//把arr2数组的内容拷贝到arr1中
	printf("%s\n", arr1);
	return 0;
}

?特点:

(1)源字符串必须以 '\0' 结束;
(2)该函数会将源字符串中的 '\0' 拷贝到目标空间之中;
(3)目标空间必须足够大,以确保能存放源字符串;
(4)目标空间必须可变。
int main()
{
    char * arr1="abcdef";
    char arr2[20]={0};
    strcpy(arr1,arr2);//arr1指向常量字符串,常量字符串不可修改
    return 0;
}

strcpy函数的模拟实现

char* my_strcpy(char * dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
3、 strcat——字符串追加
//代码演示
int main()
{
	char arr1[20] = "hello";
	char arr2[] = " bit";
	printf("%s\n", strcat(arr1, arr2));
	return 0;
}

?特点:

(1)源字符串必须以 '\0' 结束;
(2)目标空间必须有足够的大,能容纳下源字符串的内容;
(3)目标空间必须可修改。
(4)追加时,会把目标字符串最开始的'\0'覆盖了
int main()
{
	char arr1[20] = "xxxx\0xxxxxxxxxxxx";
	char arr2[] = " bit";
	strcat(arr1, arr2);
	return 0;
}

strcat函数的模拟实现

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

?那么能不能自己对自己追加呢?——不能,会导致死循环

?因为前面所说,追加时,会把目标字符串最开始的'\0'覆盖了,而目标字符串就是源字符串,这时就和第(1)条源字符串必须以 '\0' 结束矛盾,所以不能。

4、strcmp——字符串比较

标准规定:
(1)第一个字符串大于第二个字符串,则返回大于 0 的数字;
(2)第一个字符串等于第二个字符串,则返回 0;
(3)第一个字符串小于第二个字符串,则返回小于 0 的数字。

特点:比较的不是字符串的长度,而是比较的时字符串对应位置上的字符大小,如果相同,就比较下一对,直到不同或者遇到‘\0’。

//使用演示
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdf";
	printf("%d\n", strcmp(arr1, arr2));
	return 0;
}

?strcmp函数的模拟实现

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

前面所说的字符串函数都是长度不受限制的字符串函数——strcpy、strcat、strcmp

而接下来所说的时长度受限制的字符串函数——strncpy、strncat、strncmp

5、strncpy

char * strncpy ( char * destination , const char * source , size_t num );
(1)拷贝 num 个字符从源字符串到目标空间。
(2)如果源字符串的长度小于 num ,则拷贝完源字符串之后,在目标的后边追加 0 ,直到 num 个。
//代码演示
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	printf("%s\n", strncpy(arr1, arr2, 4)); 
    return 0; 
}

6、strncat

char * strncat ( char * destination , const char * source , size_t num );
(1)追加了num个字符后,还会在目标字符串后再追加一个'\0'。
//演示
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "abcdef";
	printf("%s\n", strncat(arr1, arr2, 4));
	return 0;
}

7、strncmp

int strncmp ( const char * str1 , const char * str2 , size_t num );
(1)比较到出现其中一个字符不一样或者其中一个字符串结束或者num个字符全部比较完。
//演示
int main()
{
	char arr1[20] = "abcdefhij";
	char arr2[] = "abcdeg";
	printf("%d\n", strncmp(arr1, arr2, 6));
	return 0;
}

8、strstr——看一个字符串是否为另一个字符串的字串?

(1)如果是子串,则返回的是源字符串中子串的起始地址;如果不是,则返回空指针。
//演示
int main()
{
	char arr1[20] = "abcdeabcdefgh";
	char arr2[] = "abcdef";
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("找不到字串\n");
	}
	else
		printf("%s\n", ret);
	return 0;
}

strstr函数的模拟实现

char* my_strstr(char* str1, char* str2)
{
	char* s1 = str1;
	char* s2 = str2;
	char* cur = str1;
	while (*cur)
	{
		s1 = cur;
		s2 = str2;
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cur;
		}
		cur++;
	}
	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 ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。 如果字符串中不存在更多的标记,则返回 NULL 指针。
int main()
{
	char arr1[20] = "1447155263@qq.com";
	char arr2[20] = {0};
	strcpy(arr2, arr1);
	char* sep = "@.";
	printf("%s\n", strtok(arr2, sep));
	printf("%s\n", strtok(NULL, sep));
	printf("%s\n", strtok(NULL, sep));
	return 0;
}

10、strerror——返回错误码所对应的错误信息

?字符分类函数:

int main()
{
	if (isdigit('4'))
		printf("是十进制数字\n");
	return 0;
}

?字符转换:

int tolower ( int c ); //转小写
int toupper ( int c ); //转大写
#include<ctype.h>
int main()
{
	char ch = 'a';
	putchar(toupper(ch));
	return 0;
}

?

内存操作函数

memcpy ;memmove ; memcmp ;memset?

11、memcpy

void * memcpy ( void * destination , const void * source , size_t num );
(1)函数 memcpy source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。
(2)这个函数在遇到 '\0' 的时候并不会停下来。
(3)如果source destination 有任何的重叠,复制的结果都是未定义的。
//演示
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[5] = { 0 };
	memcpy(arr2, arr1, 20);
	return 0;
}

?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;
}

12、memmove——重叠内存拷贝

void * memmove ( void * destination , const void * source , size_t num );
(1)和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
(2)如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(arr1+2, arr1, 20);
	return 0;
}

??memmove的模拟实现

void* my_memmove(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;

		if (src > dest)//前——>后
		{
			while (count--)
			{
				*(char*)dest = *(char*)src;
				dest = (char*)dest + 1;
				src = (char*)src + 1;
			}
		}
		else
		{
			while (count--)
			{
				*((char*)dest + count) = *((char*)src + count);
			}
		}
		return ret;
}

这里有一点要注意的,如果dest<src,那么src要从前向后拷贝到dest中,如果dest>src,则要从后向前拷贝。因为不这样可能会导致要拷贝的部分被覆盖。

13 memcmp——内存比较
int memcmp ( const void * ptr1 , const void * ptr2 , size_t num );
(1)比较从 ptr1 ptr2 指针开始的 num 个字节
//演示
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,0x1223305 };
	int ret = memcmp(arr1, arr2, 16);
	return 0;
}

14memset——内存设置

以字节为单位来初始化,会改动每个字节,而不是每个元素

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:42:53  更:2022-04-04 12:45:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/26 12:26:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码