web-dev-qa-db-ja.com

C言語でchar配列をコピーする方法

Cでは、2つのchar配列があります。

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

array1の値をarray2にコピーする方法array2 = array1だけできますか?

64
user2131316

array2 = array1を直接実行することはできません。この場合、配列のアドレス(char *)を操作し、それらの値を操作しないためです。

このような状況では、特にarray1がユーザー入力(キーボード、ネットワークなど)から埋められる場合は、 strncpy を回避するために バッファオーバーフロー を使用することをお勧めします。そのようです:

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

@Profとして。 Falkenはコメントで述べました、strncpy悪くなることがあります 。ターゲットバッファがソースバッファを含むのに十分な大きさであることを確認してください(文字列の最後に\0を含む)。

74
aymericbeaumet

配列が文字列配列ではない場合は、次のようにします。memcpy(array2, array1, sizeof(array2));

23
kAmol

あらゆる種類の問題を引き起こす可能性がある終端されていない文字列から保護したい場合は、次のように文字列をコピーします。

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バイトにnullバイトがない場合、destに配置された文字列はnullで終了しません。」

Strncpy()がこのやや奇妙な方法で振る舞う理由は、文字列をコピーする安全な方法として本来意図されていなかったからです。

もう1つの方法は、strcpy()の代わりにsnprintf()を使用することです。

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

(ありがとう jxh チップをありがとう。)

22
Prof. Falken

配列を割り当てることはできません。名前は変更できない定数です。

あなたはcontentsをコピーすることができます:

strcpy(array2, array1);

あなたの例のように、ソースが有効な文字列で、デスティネーションが十分に大きいと仮定します。

6
unwind

他の人が指摘したように、文字列は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 */

「decay to pointer value」セマンティックが導入された理由については、これはCの前身とのソースコードの互換性を実現するためでした。C言語の開発詳細。

4
jxh

これは次のようになります。

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

char src[6] = "Hello";
char dest[6];
cstringcpy(src, dest);
3
Boris
array2 = array1;

cではサポートされていません。そのためには strcpy() のような関数を使わなければなりません。

1
MOHAMED

以下のc関数のみ... c ++あなたはchar配列をする必要があり、それから文字列コピーを使用し、次に文字列tokenizor関数を使用します。

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

データのコピーにはmemcpy()を使うことをお勧めします。また、バッファをarray2 = array1として別のバッファに割り当てると、両方の配列は同じメモリを持ち、arrary1の変更はarray2でも偏向します。しかし、私たちはmemcpyを使います、両方のバッファは異なる配列を持ちます。 strcpyと関連関数はNULL文字をコピーしないので、memcpy()をお勧めします。

1
akhil

整数型の場合

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

まあ、技術的にあなたは…

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" */

しかし、それは非常に美しく見えないでしょう。

(はい、上記のコードは 付与された 常に動作するようになっており、移植性があります)

0
madmurphy

配列を割り当ててコピーすることはできません。あるコンテンツを別のコンテンツにコピーする方法は、複数の要因によって異なります。

char配列の場合、ソース配列がnullで終了し、デスティネーション配列がnull配列を含むソース配列内の文字列に対して十分な大きさであることがわかっている場合は、strcpy()を使用します。

#include <string.h>

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

...

strcpy(array2, array1);

デスティネーション配列が十分大きいかどうかわからないが、ソースがC文字列で、デスティネーションを適切なC文字列にしたい場合は、snprinf()を使用します。

#include <stdio.h>

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

...

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

ソース配列が必ずしもNULL終端されていなくても、両方の配列のサイズが同じであることがわかっている場合は、memcpyを使用できます。

#include <string.h>

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

...

memcpy(array2, array1, sizeof array2);
0
chqrlie