简体   繁体   English

如何在 C 中复制一个字符数组?

[英]How to copy a char array in C?

In C, I have two char arrays:在 C 中,我有两个字符 arrays:

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

How to copy the value of array1 to array2 ?如何将array1的值复制到array2 Can I just do this: array2 = array1 ?我可以这样做吗: array2 = array1

You can't directly do array2 = array1 , because in this case you manipulate the addresses of the arrays ( char * ) and not of their inner values ( char ).您不能直接执行array2 = array1 ,因为在这种情况下,您操作的是数组的地址 ( char * ) 而不是它们的内部值 ( char )。

What you, conceptually, want is to do is iterate through all the chars of your source ( array1 ) and copy them to the destination ( array2 ).从概念上讲,您想要做的是遍历源 ( array1 ) 的所有字符并将它们复制到目标 ( array2 )。 There are several ways to do this.有几种方法可以做到这一点。 For example you could write a simple for loop, or use memcpy .例如,您可以编写一个简单的 for 循环,或使用memcpy

That being said, the recommended way for strings is to use strncpy .话虽如此,字符串的推荐方法是使用strncpy It prevents common errors resulting in, for example, buffer overflows (which is especially dangerous if array1 is filled from user input: keyboard, network, etc).它可以防止导致例如缓冲区溢出的常见错误(如果array1是从用户输入填充的,则特别危险:键盘、网络等)。 Like so:像这样:

// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);

As @Prof.作为@Prof。 Falken mentioned in a comment, strncpy can be evil . Falken 在评论中提到, strncpy 可能是 evil Make sure your target buffer is big enough to contain the source buffer (including the \\0 at the end of the string).确保您的目标缓冲区足够大以包含源缓冲区(包括字符串末尾的\\0 )。

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

If you want to guard against non-terminated strings, which can cause all sorts of problems, copy your string like this:如果您想防止可能导致各种问题的未终止字符串,请像这样复制您的字符串:

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

size_t destination_size = sizeof (array2);

strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';

That last line is actually important, because strncpy() does not always null terminate strings.最后一行实际上很重要,因为strncpy()并不总是空终止字符串。 (If the destination buffer is too small to contain the whole source string, sntrcpy() will not null terminate the destination string.) (如果目标缓冲区太小而无法包含整个源字符串,则 sntrcpy() 不会空终止目标字符串。)

The manpage for strncpy() even states "Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated." strncpy() 的联机帮助页甚至指出“警告:如果 src 的前 n 个字节中没有空字节,则放置在 dest 中的字符串不会以空值结尾。”

The reason strncpy() behaves this somewhat odd way, is because it was not actually originally intended as a safe way to copy strings. strncpy() 表现出这种有点奇怪的方式的原因是因为它实际上最初并不是作为复制字符串的安全方式。

Another way is to use snprintf() as a safe replacement for strcpy():另一种方法是使用 snprintf() 作为 strcpy() 的安全替代品:

snprintf(array2, destination_size, "%s", array1);

(Thanks jxh for the tip.) (感谢jxh的提示。)

You cannot assign arrays, the names are constants that cannot be changed.您不能分配数组,名称是无法更改的常量。

You can copy the contents , with:您可以复制内容,使用:

strcpy(array2, array1);

assuming the source is a valid string and that the destination is large enough, as in your example.假设源是有效字符串并且目标足够大,如您的示例所示。

As others have noted, strings are copied with strcpy() or its variants.正如其他人所指出的,字符串是用strcpy()或其变体复制的。 In certain cases, you could use snprintf() as well.在某些情况下,您也可以使用snprintf()

You can only assign arrays the way you want as part of a structure assignment:作为结构分配的一部分,您只能以您想要的方式分配数组:

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

array2 = array1;

If your arrays are passed to a function, it will appear that you are allowed to assign them, but this is just an accident of the semantics.如果你的数组被传递给一个函数,看起来你被允许分配它们,但这只是语义的一个意外。 In C, an array will decay to a pointer type with the value of the address of the first member of the array, and this pointer is what gets passed.在 C 中,数组将衰减为具有数组第一个成员地址值的指针类型,并且传递的是该指针。 So, your array parameter in your function is really just a pointer.因此,函数中的数组参数实际上只是一个指针。 The assignment is just a pointer assignment:赋值只是一个指针赋值:

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

The array itself remains unchanged after returning from the function.从函数返回后,数组本身保持不变。

This "decay to pointer value" semantic for arrays is the reason that the assignment doesn't work.数组的这种“衰减到指针值”语义是赋值不起作用的原因。 The l-value has the array type, but the r-value is the decayed pointer type, so the assignment is between incompatible types.左值具有数组类型,但右值是衰减的指针类型,因此分配是在不兼容的类型之间进行的。

char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
                    but array2 is still an array type */

As to why the "decay to pointer value" semantic was introduced, this was to achieve a source code compatibility with the predecessor of C. You can read The Development of the C Language for details.至于为什么引入“decay to pointer value”语义,这是为了实现与C的前身的源代码兼容,详见C语言的发展

it should look like this:它应该是这样的:

void cstringcpy(char *src, char * dest)
{
    while (*src) {
        *(dest++) = *(src++);
    }
    *dest = '\0';
}
.....

char src[6] = "Hello";
char dest[6];
cstringcpy(src, dest);

I recommend to use memcpy() for copying data.我建议使用 memcpy() 来复制数据。 Also if we assign a buffer to another as array2 = array1 , both array have same memory and any change in the arrary1 deflects in array2 too.此外,如果我们将一个缓冲区分配给另一个数组array2 = array1 ,则两个数组都具有相同的内存,并且 arrary1 中的任何更改也会在 array2 中偏转。 But we use memcpy, both buffer have different array.但是我们使用 memcpy,两个缓冲区都有不同的数组。 I recommend memcpy() because strcpy and related function do not copy NULL character.我推荐 memcpy() 因为 strcpy 和相关函数不会复制 NULL 字符。

array2 = array1;

is not supported in c.在 c 中不支持。 You have to use functions like strcpy() to do it.您必须使用strcpy() 之类的函数来执行此操作。

c functions below only ... c++ you have to do char array then use a string copy then user the string tokenizor functions... c++ made it a-lot harder to do anythng c 函数仅低于... c++ 你必须做字符数组然后使用字符串副本然后使用字符串标记器函数... c++ 使得做任何事情都变得更加困难

#include <iostream>
#include <fstream>
#include <cstring>
#define TRUE 1
#define FALSE 0
typedef int Bool;
using namespace std;
Bool PalTrueFalse(char str[]);
int main(void)
{
char string[1000], ch;
int i = 0;
cout<<"Enter a message: ";

while((ch = getchar()) != '\n') //grab users input string untill 
{                               //Enter is pressed
    if (!isspace(ch) && !ispunct(ch)) //Cstring functions checking for
    {                                //spaces and punctuations of all kinds
        string[i] = tolower(ch); 
        i++;
    }
}
string[i] = '\0';  //hitting null deliminator once users input
cout<<"Your string: "<<string<<endl; 
if(PalTrueFalse(string)) //the string[i] user input is passed after
                        //being cleaned into the null function.
    cout<<"is a "<<"Palindrome\n"<<endl;
else
   cout<<"Not a palindrome\n"<<endl;
return 0;
}

Bool PalTrueFalse(char str[])
{
int left = 0;
int right = strlen(str)-1;
while (left<right)
{
   if(str[left] != str[right]) //comparing most outer values of string
       return FALSE;          //to inner values.
   left++;
   right--;
}
return TRUE;
}

for integer types对于整数类型

#include <string.h>    

int array1[10] = {0,1,2,3,4,5,6,7,8,9};
int array2[10];


memcpy(array2,array1,sizeof(array1)); // memcpy("destination","source","size")

You cannot assign arrays to copy them.您不能分配数组来复制它们。 How you can copy the contents of one into another depends on multiple factors:如何将一个内容复制到另一个内容取决于多种因素:

For char arrays, if you know the source array is null terminated and destination array is large enough for the string in the source array, including the null terminator, use strcpy() :对于char数组,如果您知道源数组以空结尾并且目标数组对于源数组中的字符串(包括空终止符strcpy()足够大,请使用strcpy()

#include <string.h>

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

...

strcpy(array2, array1);

If you do not know if the destination array is large enough, but the source is a C string, and you want the destination to be a proper C string, use snprinf() :如果您不知道目标数组是否足够大,但源是 C 字符串,并且您希望目标是正确的 C 字符串,请使用snprinf()

#include <stdio.h>

char array1[] = "a longer string that might not fit";
char array2[18];

...

snprintf(array2, sizeof array2, "%s", array1);

If the source array is not necessarily null terminated, but you know both arrays have the same size, you can use memcpy :如果源数组不一定以 null 结尾,但您知道两个数组的大小相同,则可以使用memcpy

#include <string.h>

char array1[28] = "a non null terminated string";
char array2[28];

...

memcpy(array2, array1, sizeof array2);

Well, techincally you can…好吧,从技术上讲,您可以……

typedef struct { char xx[18]; } arr_wrap;

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

*((arr_wrap *) array2) = *((arr_wrap *) array1);

printf("%s\n", array2);     /* "abcdefg" */

but it will not look very beautiful.但它看起来不会很漂亮。

…Unless you use the C preprocessor… ……除非你使用 C 预处理器……

#define CC_MEMCPY(DESTARR, SRCARR, ARRSIZE) \
    { struct _tmparrwrap_ { char xx[ARRSIZE]; }; *((struct _tmparrwrap_ *) DESTARR) = *((struct _tmparrwrap_ *) SRCARR); }

You can then do:然后你可以这样做:

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

CC_MEMCPY(array2, array1, sizeof(array1));

printf("%s\n", array2);     /* "abcdefg" */

And it will work with any data type, not just char :它适用于任何数据类型,而不仅仅是char

int numbers1[3] = { 1, 2, 3 };
int numbers2[3];

CC_MEMCPY(numbers2, numbers1, sizeof(numbers1));

printf("%d - %d - %d\n", numbers2[0], numbers2[1], numbers2[2]);     /* "abcdefg" */

(Yes, the code above is granted to work always and it's portable) (是的,上面的代码被授予始终工作并且是可移植的)

None of the above was working for me.. this works perfectly name here is char *name which is passed via the function以上都没有为我工作..这完美的name在这里是通过函数传递的char *name

  1. get length of char *name using strlen(name)使用strlen(name)获取char *name长度
  2. storing it in a const variable is important将其存储在 const 变量中很重要
  3. create same length size char array创建相同长度大小的char数组
  4. copy name 's content to temp using strcpy(temp, name);使用strcpy(temp, name);name的内容复制到temp strcpy(temp, name);

use however you want, if you want original content back.如果您想要原始内容,请随意使用。 strcpy(name, temp); copy temp back to name and voila works perfectly将 temp 复制回name并且 voila 完美运行

    const int size = strlen(name);
    char temp[size];
    cout << size << endl;
    strcpy(temp, name);

You can't copy directly by writing array2 = array1 .您不能通过编写array2 = array1直接复制。

If you want to copy it manually , iterate over array1 and copy item by item as follows -如果您想手动复制它,请遍历array1并逐项复制,如下所示 -

int i;
for(i=0;array1[i]!='\0';i++){
 array2[i] = array1[i]; 
}
array2[i]='\0'; //put the string terminator too

If you are ok to use string library , you can do it as follows -如果您可以使用字符串库,您可以按如下方式进行 -

strncpy ( array2, array1, sizeof(array2) );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM