如何在C中复制char数组?

use*_*316 68 c arrays copy char

在C中,我有两个char数组:

char array1[18] = "abcdefg";
char array2[18];
Run Code Online (Sandbox Code Playgroud)

如何复制的价值array1array2?我可以这样做array2 = array1吗?

aym*_*met 77

你不能直接做array2 = array1.因为在这种情况下,您将操纵char *数组的地址()而不是它们的值.

对于这种情况,建议使用strncpy以避免缓冲区溢出,特别是如果array1从用户输入(键盘,网络等)填充.像这样:

// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);
Run Code Online (Sandbox Code Playgroud)

作为@Prof.法尔肯在评论中提到,strncpy 可能是邪恶的.确保目标缓冲区足够大以包含源缓冲区(包括\0字符串末尾).

  • @ user2131316:这是因为数组名称在语义上转换为指针值的方式.我在答案中解释了这一点. (2认同)

kAm*_*mol 28

如果您的数组不是字符串数组,请使用: memcpy(array2, array1, sizeof(array2));

  • memcpy的第一个参数是目标数组,它应该是array2! (18认同)
  • @Wecherowski:当您将数组传递给函数时,它会降级为指针。在该函数中,您不能使用“sizeof()”来确定数组的大小。否则,“sizeof()”可以很好地完成该任务。 (2认同)

Pro*_*ica 24

如果你想防止可能导致各种问题的非终止字符串,请复制你的字符串,如下所示:

char array1[18] = {"abcdefg"};
char array2[18];

size_t destination_size = sizeof (array2);

strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';
Run Code Online (Sandbox Code Playgroud)

最后一行实际上很重要,因为strncpy()并不总是null终止字符串.(如果目标缓冲区太小而不能包含整个源字符串,则sntrcpy()将不会终止目标字符串.)

strncpy()的联机帮助页甚至声明"警告:如果src的前n个字节中没有空字节,则放在dest中的字符串将不会以空值终止."

strncpy()的行为有点奇怪,因为它实际上并不是最初用来复制字符串的安全方法.

另一种方法是使用snprintf()作为strcpy()的安全替代品:

snprintf(array2, destination_size, "%s", array1);
Run Code Online (Sandbox Code Playgroud)

(谢谢jxh的提示.)

  • 注意`snprintf()`没有`strncpy()`的问题. (2认同)

unw*_*ind 6

您无法分配数组,名称是无法更改的常量.

您可以复制内容,包括:

strcpy(array2, array1);
Run Code Online (Sandbox Code Playgroud)

假设源是一个有效的字符串,并且目标足够大,如示例所示.


jxh*_*jxh 6

正如其他人所指出的,字符串strcpy()与其变体一起被复制。在某些情况下,您也可以使用snprintf()

作为结构分配的一部分,您只能以您想要的方式分配数组:

typedef struct { char a[18]; } array;
array array1 = { "abcdefg" };
array array2;

array2 = array1;
Run Code Online (Sandbox Code Playgroud)

如果你的数组被传递给一个函数,看起来你被允许分配它们,但这只是语义的一个意外。在 C 中,数组将衰减为具有数组第一个成员地址值的指针类型,并且传递的是该指针。因此,函数中的数组参数实际上只是一个指针。赋值只是一个指针赋值:

void foo (char x[10], char y[10]) {
    x = y;    /* pointer assignment! */
    puts(x);
}
Run Code Online (Sandbox Code Playgroud)

从函数返回后,数组本身保持不变。

数组的这种“衰减到指针值”语义是赋值不起作用的原因。左值具有数组类型,但右值是衰减的指针类型,因此赋值是在不兼容的类型之间进行的。

char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
                    but array2 is still an array type */
Run Code Online (Sandbox Code Playgroud)

至于为什么引入“decay to pointer value”语义,这是为了实现与C的前身的源代码兼容,详见C语言的发展