返回

字符串函数与内存函数(day22)

发布时间:2023-04-13 02:56:31 371
# 数据

strstr函数

实例

int main()
{
char arr1[20] = "abcdef";
char arr2[20] = "de";
char* ret = strstr(arr1, arr2);
if (ret == NULL)
printf("没有找到\n");
else
printf("找到了,匹配地址为%p\n", ret);

return 0;

strstr函数,传参为(查找字符串数组,匹配字符串数组),匹配不到查找值,返回空指针。匹配到字符串,返回首个匹配元素的地址。

注意:为全部匹配

实例复现

char* my_strstr(const char* str1,const char *str2)
{
assert(str1);
assert(str2);
char *s1=NULL;
char *s2=NULL;
char *cur=str1;

//如果子串一开始就是空,那么直接返回母串
if(*str2=='\0')
{
return *str1;
}

while(*cur!='\0')
{
s1=cur;
s2=str2;
while((*s1==*s2)&&*s1&&*s2)//s1和s2不能走到\0
{
s1++;
s2++;
}

if(*s2=='\0')
{
return cur;
}

cur++;
}

return NULL;

}

memcpy函数

内存拷贝函数,当操作对象不是字符串数组,比如整型数组时,字符串函数strcpy显然无法通过读取字符数组中的\0来实现对其他类型数组的操作,这时候可以考虑直接将内存中的数据拷贝到指定位置,使用memcpy函数。

字符串函数与内存函数(day22)_字符串数组

其形式类似于strncpy函数。即复制指定字节的数据至dst数组内。

实例

int main()
{
int arr1[10] = { 1,2,3,4,5 };
int arr2[3] = { 3,6,9 };
int i = 0;
memcpy(arr1, arr2, sizeof(arr2));
for (i = 0; i < sizeof(arr1); i++)
{
printf("%5d", arr1[i]);
}
return 0;
}

结果

   3    6    9    4    5    0    0    0    0    0-858993460-858993460-858993460-858993460-858993460-858993460    3    6     9

中间出现的随机值因为sizeof()操作符计算得40个字节,打印了40个字节的数据。超出数组范围了.

字符串函数与内存函数(day22)_字符串数组_02

字符串函数与内存函数(day22)_数据_03

字符串函数与内存函数(day22)_数组_04

字符串函数与内存函数(day22)_数据_05

字符串函数与内存函数(day22)_字符串数组_06

复现函数

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

int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[5] = { 0 };

my_memcpy(arr2, arr1, (size_t)sizeof(arr1));

return 0;
}

错误示例

int main()
{
int arr1[10] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
memcpy(arr1, (const void*)arr1[2], 12);
return 0;
}

报错

字符串函数与内存函数(day22)_字符串数组_07

当强制转换arr1内某元素的地址数组为const void*,再通过函数memcpy进行同一数组的内部复制时会发生错误。

源数组传递的指针为const类型无法更改,而更改的就是已经在访问的数组,结果就是实参传递给型参时报错。

字符串函数与内存函数(day22)_字符串数组_08

即使编译过去以后,变量也未发生改变。当源指针所指定的元素与目的地指针的元素发生冲突时,就会用到memmove函数。

memmove函数

memmove用于拷贝字节,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。

void *memmove(void *str1, const void *str2, size_t n) 

从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。

实例

int main()
{
int arr1[10] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
int i;
memmove(arr1, arr1+2, 12);//步长为4字节,arr1+2即从第三个数开始,复制12个字节即三个元素
for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
{
printf("%5d",arr1[i]);
}
return 0;
}

结果

    3    4    5    4    5    0    0    0    0    0

复现实例

void* my_memmove(void* dest, const void* sour, size_t num)
{
void* temp = dest;
assert(dest && sour);
char* dest1 = (char*)dest;
char* sour1 = (char*)sour;
//判断源地址和目标地址的大小,决定是倒序复制还是正序复制
if (dest1 > sour1)
{
//倒序复制
while (num--)
{
*(dest1 + num) = *(sour1 + num);
}
}
else if (dest1 < sour1)
{
//正序复制
while (num--)
{
*(dest1) = *(sour1);
dest1++;
sour1++;
}
}
return temp;
}

int main()
{
int arr1[10] = { 1,1,2,2,3,3,4,4,5,5 };
int i ;
my_memmove(arr1 + 2, arr1, 8);
return 0;
}

代码调试

字符串函数与内存函数(day22)_字符串数组_09

字符串函数与内存函数(day22)_数据_10

字符串函数与内存函数(day22)_数组_11

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
SGX性能实验 2023-04-13 00:07:59