Development Tip

C에서 char 배열을 복사하는 방법은 무엇입니까?

yourdevel 2020. 11. 10. 22:23
반응형

C에서 char 배열을 복사하는 방법은 무엇입니까?


C에서는 두 개의 문자 배열이 있습니다.

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

어떻게 값 복사 array1에를 array2? 그냥 할 수 있습니까 array2 = array1?


array2 = array1이 경우 char *값이 아니라 배열 의 주소 ( )를 조작하기 때문에 직접 할 수 없습니다 .

이러한 상황에서는 특히 사용자 입력 (키보드, 네트워크 등)에서 채워진 경우 버퍼 오버플로strncpy 를 방지하기 위해 사용 하는 것이 좋습니다 . 이렇게 :array1

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

@Prof. 댓글에 언급 된 Falken strncpy 은 악할 수 있습니다 . 대상 버퍼가 소스 버퍼를 포함 할 수있을만큼 충분히 큰지 확인하십시오 ( \0문자열 끝 포함 ).


배열이 string 형 배열이 아닌 경우 다음을 사용하십시오. memcpy(array2, array1, sizeof(array2));


모든 종류의 문제를 일으킬 수있는 종료되지 않은 문자열에 대해 보호하려면 다음과 같이 문자열을 복사하십시오.

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

size_t destination_size = sizeof (array2);

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

마지막 줄은 strncpy()항상 null로 끝나는 문자열 이 아니기 때문에 실제로 중요 합니다. (대상 버퍼가 너무 작아 전체 소스 문자열을 포함 할 수없는 경우 sntrcpy ()는 대상 문자열을 null로 종료하지 않습니다.)

strncpy ()의 맨 페이지에는 "경고 : src의 처음 n 바이트 중에 널 바이트가 없으면 dest에 배치 된 문자열이 널로 종료되지 않습니다."라고 명시되어 있습니다.

strncpy ()가 다소 이상한 방식으로 동작하는 이유는 원래 문자열을 복사하는 안전한 방법이 아니기 때문입니다.

또 다른 방법은 snprintf ()를 strcpy ()의 안전한 대체물로 사용하는 것입니다.

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

( 팁에 대해 jxh 에게 감사드립니다 .)


배열을 할당 할 수 없으며 이름은 변경할 수없는 상수입니다.

다음을 사용하여 내용을 복사 할 수 있습니다 .

strcpy(array2, array1);

소스가 유효한 문자열이고 예에서와 같이 대상이 충분히 크다고 가정합니다.


다른 사람들이 언급했듯이 문자열은 strcpy()또는 그 변형 과 함께 복사됩니다 . 어떤 경우에는 사용할 수도 있습니다 snprintf().

구조 할당의 일부로 원하는 방식으로 만 배열을 할당 할 수 있습니다.

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

array2 = array1;

배열이 함수에 전달되면 할당이 허용 된 것처럼 보이지만 이는 의미론의 우연 일뿐입니다. C에서 배열은 배열의 첫 번째 멤버의 주소 값을 가진 포인터 유형으로 감쇠되며이 포인터가 전달됩니다. 따라서 함수의 배열 매개 변수는 실제로 포인터입니다. 할당은 포인터 할당 일뿐입니다.

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

배열 자체는 함수에서 돌아온 후에도 변경되지 않습니다.

배열에 대한이 "포인터 값 감소"의미는 할당이 작동하지 않는 이유입니다. l- 값에는 배열 유형이 있지만 r- 값은 붕괴 된 포인터 유형이므로 호환되지 않는 유형간에 할당됩니다.

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

"포인터 값 감소"의미 체계가 도입 된 이유는 C의 이전 버전과 소스 코드 호환성을 달성하기위한 것입니다. 자세한 내용 은 The Development of the C Language읽을 수 있습니다 .


다음과 같아야합니다.

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

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

array2 = array1;

c에서는 지원되지 않습니다. 이를 위해서는 strcpy () 와 같은 함수를 사용해야 합니다.


데이터 복사에는 memcpy ()를 사용하는 것이 좋습니다. 또한 버퍼를 다른 것에 할당하면 array2 = array1두 배열 모두 동일한 메모리를 가지며 arrary1의 변경 사항은 array2에서도 반사됩니다. 그러나 우리는 memcpy를 사용하며 두 버퍼는 서로 다른 배열을 가지고 있습니다. strcpy 및 관련 함수는 NULL 문자를 복사하지 않기 때문에 memcpy ()를 권장합니다.


아래의 c 함수 만 ... c ++ 문자 배열을 수행 한 다음 문자열 복사를 사용하고 문자열 tokenizor 함수를 사용합니다 ... C ++는 anythng를 수행하기가 훨씬 더 어려워졌습니다.

#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;
}

정수 유형의 경우

#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")

복사 할 어레이를 할당 할 수 없습니다. 한 콘텐츠를 다른 콘텐츠로 복사하는 방법은 여러 요인에 따라 다릅니다.

들어 char당신이 알고있는 경우 배열, 소스 배열이 null 종료하고 대상 배열이 널 터미네이터, 사용을 포함하여 소스 배열의 문자열에 대한 충분한입니다 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():

#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:

#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.

(Yes, the code above is granted to work always and it's portable)

참고URL : https://stackoverflow.com/questions/16645583/how-to-copy-a-char-array-in-c

반응형