memcpy,用于将固定长度的缓冲区复制到结构中

memcpy,用于将固定长度的缓冲区复制到结构中,c,C,我有以下示例代码: struct { char a[2]; char b[2]; } buff; char buffer1[5] = "ABCD"; 要将buffer1复制到结构成员,我的操作如下: char c[3],d[3]; memcpy(&buff,buffer1,4); sprintf(c,"%2.2s",buff.a); sprintf(d,"%2.2s",buff.b); printf("c=%s,d=%s",c,d); 当我打印变量c和d时,我正确地

我有以下示例代码:

struct
{
    char a[2];
    char b[2];
} buff;

char buffer1[5] = "ABCD";
要将
buffer1
复制到结构成员,我的操作如下:

char c[3],d[3];
memcpy(&buff,buffer1,4);
sprintf(c,"%2.2s",buff.a);
sprintf(d,"%2.2s",buff.b);
printf("c=%s,d=%s",c,d);
当我打印变量c和d时,我正确地获得了c和d变量中的值:
c=“AB”
c=“CD”

好吧,我的问题是,即使我得到了正确的输出,
memcpy
是否会影响与空字符终止相关的任何内容,或者产生其他与内存相关的意外后果
#include<stdio.h>
#include<string.h>

struct
{
        char a[2];
        char b[2];
}buff;

int main ( void )
{

        char buffer1[4] = "ABCD";

        memcpy ( &buff , buffer1 , 4 );

        printf ( "\n%s\n ", buff.a );
        printf ( "\n%s\n ", buff.b );

        return ( 0 );
}

o/p-->
 rabi@rabi-VirtualBox:~/rabi/c$ gcc 16.c 
rabi@rabi-VirtualBox:~/rabi/c$ ./a.out 

ABCD

CD
 rabi@rabi-VirtualBox:~/rabi/c$

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

struct
{
        char a[3];
        char b[3];
}buff;

int main ( void )
{
        char buffer1[4] = "ABCD";

        memcpy ( &buff.a , &buffer1[0], 2 );
        buff.a[2]='\0';
        memcpy ( &buff.b , &buffer1[2], 2 );
        buff.b[2]='\0';

        printf ( "\n%s\n ", buff.a );
        printf ( "\n%s\n ", buff.b );

        return ( 0 );
}

o/p--->
 rabi@rabi-VirtualBox:~/rabi/c$ gcc 15.c 
rabi@rabi-VirtualBox:~/rabi/c$ ./a.out 

AB

CD
 rabi@rabi-VirtualBox:~/rabi/c$ 
#包括 结构 { chara[2]; charb[2]; }浅黄色; 内部主(空) { 字符缓冲区1[4]=“ABCD”; memcpy(&buff,buffer1,4); printf(“\n%s\n”,buff.a); printf(“\n%s\n”,buff.b); 返回(0); } o/p--> rabi@rabi-虚拟箱:~/rabi/c$gcc 16.c rabi@rabi-虚拟箱:~/rabi/c$/a.out ABCD 光盘 rabi@rabi-虚拟盒:~/rabi/c$ #包括 #包括 结构 { chara[3]; charb[3]; }浅黄色; 内部主(空) { 字符缓冲区1[4]=“ABCD”; memcpy(&buff.a,&buffer1[0],2); buff.a[2]='\0'; memcpy(&buff.b,&buffer1[2],2); buff.b[2]='\0'; printf(“\n%s\n”,buff.a); printf(“\n%s\n”,buff.b); 返回(0); } o/p---> rabi@rabi-虚拟箱:~/rabi/c$gcc 15.c rabi@rabi-虚拟箱:~/rabi/c$/a.out AB 光盘 rabi@rabi-虚拟箱:~/rabi/c$
buffer1
以null结尾。但是,
buff
的数据成员不是,因为您没有在它们上面附加空终止符。此外,您没有空终止符的空间

所以,不,它不会影响它,因为它不在那里。当您尝试使用
stdio.h
的函数时,您会得到意外的结果,这些函数要求以null结尾的字符串



另外,您可能想检查我的示例,关于结构中的循环,它在某种程度上是相关的。我建议您一次复制到一个数据成员,而不是一次性复制。

这里有两个问题:

1) 如注释中所述,您可能忘记了在结尾
“\0”
(即ASCII中的
NUL
)终止符字符中包含空格。
printf
函数的
%s
格式说明符要求字符串的格式有效。但是,没有任何东西可以阻止您按字符顺序打印,如下所示:

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

struct {
    char a[2];
    char b[2];
} buff;

char buffer1[5] = "ABCD";

int main(void)
{
    memcpy(&buff, buffer1, 4);

    printf("First member: %c%c\n", buff.a[0], buff.a[1]);
    printf("Second member: %c%c\n", buff.b[0], buff.b[1]);

    return 0;
}

这可能不会像预期的那样起作用。结构中的字段之间可能存在填充字节。这些字段插入字段之间,以使下一个字段以某个地址偏移量开始。这主要是CPU的字大小或总线大小,或缓存对齐的倍数

即使对于
char[]
,这也可能是正确的,因为这样可以使用字传输高效地移动/复制这样的数组

对于其他类型,填充是非常可能的,此外,您还必须注意endianess

还要记住,
memcpy
&朋友们完全按照他们的名字做:他们在一块内存上操作。他们不关心字符串,他们对“字符串”没有概念。插入任何NUL字节都会使它们无用,所以它们不会


请注意,此方法类似于强制转换不兼容的指针类型。很少有地方你是安全的,但大多数时候这是通往地狱的路(也就是未定义的行为)。

当我打印时,
…如何?作为
char
或作为
string
?您的结构buff没有空终止,除非您自己明确地这样做。苏拉夫,我编辑了这个问题来回答您的问题。编辑没有反映吗?。我批准了其他人建议的编辑。除此之外,我还编辑了这个问题。可能是其他人必须批准我的编辑。这应该告诉我什么?如果不是空终止,您可以得到意外的o/p。。。。所以最好在末尾加上空终止符。你应该解释你的答案,这样人们就可以理解你的想法。我已经给出了o/p,这本身就是一个很好的解释,对吗?我的不好。我应该补充一下。。谢谢你指出:)这让我的答案看起来很糟糕+这个答案加1,你的最高答案也加1,因为我不能给+2分。:)
memcpy(&buff.a, buffer1, 2); /* or replace 2 with sizeof buff.a */
memcpy(&buff.b, buffer1+2, 2);