前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >字符串和内存函数(2)

字符串和内存函数(2)

作者头像
秦jh
发布2024-01-19 10:28:04
990
发布2024-01-19 10:28:04
举报
文章被收录于专栏:c语言,c++

字符串函数

strtok函数

strtok函数的规则:

1.参数1是指定一个字符串,它包含0个或多个由参数2字符串中一个或多个分隔符分割的标记

2.参数2是个字符串,定义了用作分隔符的字符集合。

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

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

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

6.如果字符串中不存在更多的标记,则返回NULL指针。

结合下面的例子:

当执行strtok函数后,如下图:

实际上,我们切割时并不清楚需要切割几次,因此我们需要通过循环进行切割

分析:很明显,第一次打印abcd。第二次打印ef是因为,参数1为NULL,根据规则,它会从上一次保存的位置继续查找标记,第三次打印也是如此。

strerror函数

strerror是将错误码翻译成错误信息,返回错误信息的字符串的起始地址。

strerror里的参数是整形,上面是各种类型的错误信息。

C语言中使用库函数的时候,如果发生错误,会将错误码放在errno的变量中,errno是一个全局变量,可以直接使用的。如上图,我们暂时不用管别的,我们只需要知道strerror里的errno存放错误码即可。

这里,我们再简单介绍下另一个类似的函数perror。

perror函数是直接打印错误码所对应的错误信息。perror==printf+strerror。

我们简单修改下上面的代码,发现:perror里面的内容,是我们自定义的信息,在打印完我们的信息后,他会自动在后面补上:号然后加上错误信息。因此也可以知道,perror的好处就是比较方便,会自动识别错误信息。但是他也会自动打印出错误信息。

字符函数

字符分类函数

字符分类函数有如下:

因为每个函数的使用方式基本相同,我们就举一个来简单说明:

当我们使用上面的函数时,我们需用引用头文件<ctype.h>,如果函数内为真则返回不等于0的数,如果为假,则返回0。

字符转换函数

字符转换函数有tolower和toupper。他们的返回值和参数都是int,即字符的ASCII值。如下图,如果参数是小写则转换成大写,如果是大写,则不变。

内存函数

memcpy函数

memcpy函数跟strcpy函数有相似之处,不过memcpy可以拷贝任何类型。mencpy的参数1是目标空间,参数2是原始空间,参数3是拷贝的个数,单位是字节,这里指的是把arr2的前5个元素拷贝到arr1中(因为一个整形是4个字节,5个就是20个字节)。

代码语言:javascript
复制
void* my_memcpy(void* dest, const void* src, size_t sz)
{
	assert(dest && src);
	while (sz--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
}

上方是memcpy的模拟实现。

如上图,如果我们想把前五个数(1,2,3,4,5),从第3个数开始的5个数(3,4,5,6,7)拷贝过去,我们希望得到的结果是{1,2,1,2,3,4,5,8,9,10}。可是最后的结果却不是。这是因为在拷贝的重叠部分被改变了。

前面的拷贝是不重叠内存的拷贝,可以用memcpy。如果是重叠内存的拷贝,可以用memmove函数。

memmove函数

memmove函数的返回值和参数与memcpy的一模一样,如上图,使用它就能达到我们所想要的结果。

代码语言:javascript
复制
void* my_memmove(void* dest, const void* src, size_t sz)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)
	{
		//前->后
		int i = 0;
		for (i = 0; i < sz; i++)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (sz--)
		{
			*((char*)dest + sz) = *((char*)src + sz);
		}
	}
	return ret;	
}

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr+2, arr, 20);
	int i;
	for (i = 0; i < 10; i++)
		printf("%d ", arr[i]);
	return 0;
}

上方是模拟memmove函数的实现。

分析: 当原始空间的地址大于目标空间地址时,我们需要从前往后拷贝原始字符串到目标空间。

否则,我们就需要从后往前进行拷贝,这样就不会因为重叠而导致结果达不到预期。while循环中,sz--,起初sz是20,进入循环内变成19,强转后的dest+sz刚好指向最后一个字节,就能从后往前进行拷贝。

memset函数

memset函数是用来设置内存的,以字节为单位进行设置。如上图,参数1是起始地址,参数2是要设置的内容,参数3是设置的字节个数。

memcmp函数

memcmp函数与strcmp函数类似,不过strcmp函数只能进行字符串的比较,memcmp是内存块的比较,可以比较任意类型的数据。如下图:

参数1和参数2与strcmp的一样,参数3指比较前n个字节个数的数据,因为int占4个字节,比较前3个元素,大小相同则返回0。

如上图,我们比较大小的时候,不能单纯比较数字,而要看他们在内存中是怎样的,这样才能得出正确结果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 字符串函数
    • strtok函数
      • strerror函数
      • 字符函数
        • 字符分类函数
          • 字符转换函数
          • 内存函数
            • memcpy函数
              • memmove函数
                • memset函数
                  • memcmp函数
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档