strncpy和strcpy和memcpy

目录

strcpy的简单用法

strcpy的数据含 0 或者'\0' 带来的问题

strncpy

解决方案memcpy:

简单小结:


strcpy的简单用法

#include <iostream>
using namespace std;
 
int main()
{
	char str[4] = {0};
	char *p = "abc";
	strcpy(str, p);
	cout << str << endl;   // abc
 
	return 0;
}

拷贝abc到str数组,能正常输出。

strcpy的数据含 0 或者'\0' 带来的问题

  • 拷贝字符含'\0'的情况
#include <stdio.h>

int main()
{
	char str[10] = {0};
	char *p = "ab\0defg";
	strcpy(str, p);
	printf("%s", str);   // ab
  
	return 0;
}

如上,结果为ab ,并没有被完全拷贝

  • 拷贝字符含0的情况, 也是会不被完全拷贝,下面的test的调用很常见,可能传入的字符如果含 '\0'或者 0 ,那么会导致不完全拷贝。
#include <stdio.h>


void test1 (void* data)
{
    char recv[10];
    char* xx = (char*)data;
    strcpy(recv, xx);
    printf("test1 [%s]\n", recv);   // test1 [1]

}
void test2 (void* data)
{
    char recv[10];
    char* xx = (char*)data;
    strcpy(recv, xx);
    printf("test2 [%s]\n", recv);   // test2 [10]

}
int main()
{
    char str1[10] = {'1','\0',0,'1','0','1','0',0};
    test1(str1);
    char str2[10] = {'1','0',0,'1','0','1','0',0};
    test2(str2);
	return 0;
}

strncpy

  • strncopy能避免上面因字符带0产生的问题吗?很遗憾的是不会,strncpy的源码也是依据0的结束符来判断是否拷贝完成,只是限定了拷贝的个数,避免越界,比如下面这样,也是有问题的,明明strncpy要求拷贝10个,但因为出现的'\0'让拷贝失败
#include <stdio.h>


void test1 (void* data)
{
    char recv[10];
    char* xx = (char*)data;
    strncpy(recv, xx,10);
    printf("test1 [%s]\n", recv);   // test1 [12345]

}

int main()
{
    char str1[10] = {'1','2','3','4','5','\0','7'};
    test1(str1);

	return 0;
}

解决方案memcpy:

上面的方案都有毛病,那解决方案就是memcpy

#include <stdio.h>


void test1 (void* data)
{
    char recv[10];
    char* xx = (char*)data;
    memcpy(recv, xx,10);
    printf("test1 [");
    for(int i = 0; i < 10; i ++)
        printf("%c", recv[i]);   //test1 [12345789a]  第6个字符为空

        
    printf("]\n");

}

int main()
{
    char str1[10] = {'1','2','3','4','5','\0','7','8','9','a'};
    test1(str1);

	return 0;
}

但memcpy会把字符的 0 和\0一起拷贝到buffer里,用%s打印依旧会打不出 789a, 但memcpy会根据个数来定需要拷贝多少字节,不会因为0而不拷贝。

简单小结:

  • strcpy会根据结束符来限制拷贝个数,会被结束符影响。
  • strncpy会根据传入参数限制拷贝的个数,仍然会被结束符影响。
  • memcpy的拷贝仅受传入参数限定的个数影响
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用: 结果发现:memcpy在拷贝数据时与strcpystrncpy不同的是memcpy遇到 '\0' 是不会停止拷贝到。 引用: 知识点4:memcpy()函数的模拟:void* my_memcpy(void* dst, const void* src, size_t count) { ... } 引用: 代码演示:memcpy(arr2, arr1, 6); memset和memcpy是C语言中的两个函数。memset函数用于将一块内存区域的每个字节都设置为指定的值,而memcpy函数用于将一块内存区域的数据拷贝到另一块内存区域。 具体来说,memset函数的原型为void *memset(void *s, int c, size_t n),其中s是指向内存区域的指针,c是要设置的值,n是要设置的字节数。该函数会将s所指向的内存区域的每个字节都设置为c。 而memcpy函数的原型为void *memcpy(void *dest, const void *src, size_t n),其中dest是目标内存区域的指针,src是源内存区域的指针,n是要拷贝的字节数。该函数会将src所指向的内存区域的数据拷贝到dest所指向的内存区域。 需要注意的是,memcpy在拷贝数据时,不会像strcpystrncpy那样遇到 '\0' 就停止拷贝,而是会一直拷贝下去直到拷贝完指定的字节数。这是memcpystrcpystrncpy的一个区别。 在引用中给出了一个自定义的my_memcpy函数的示例代码,该函数模拟了memcpy函数的功能。 在引用中给出了一个使用memcpy函数的示例代码,该代码将字符串"abc\0def"的前6个字节拷贝到另一个字符数组中。 综上所述,memset和memcpy是C语言中用于操作内存的两个函数,分别用于设置内存区域的值和拷贝内存区域的数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [内存函数:memcpy、memmove、memcmp、memset(超详细讲解,小白一看就懂!!!!)](https://blog.csdn.net/weixin_45031801/article/details/127481057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值