web-dev-qa-db-fra.com

Comment copier un tableau de caractères en C?

En C, j'ai deux tableaux de caractères:

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

Comment copier la valeur de array1 dans array2? Puis-je simplement faire ceci: array2 = array1?

65
user2131316

Vous ne pouvez pas faire directement array2 = array1, car dans ce cas, vous manipuleriez les adresses (char *) des tableaux et non leurs valeurs.

Pour ce genre de situation, il est recommandé d'utiliser strncpy pour éviter un débordement de tampon , en particulier si array1 est rempli à partir d'une entrée utilisateur (clavier, réseau, etc.). .) Ainsi:

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

Comme @Prof. Falken a mentionné dans un commentaire, strncpypeut être mauvais . Assurez-vous que le tampon cible est suffisamment grand pour contenir le tampon source (y compris le \0 à la fin de la chaîne).

77
aymericbeaumet

Si vos tableaux ne sont pas des tableaux de chaînes, utilisez: memcpy(array2, array1, sizeof(array2));

25
kAmol

Si vous souhaitez vous protéger contre les chaînes non terminées, qui peuvent causer toutes sortes de problèmes, copiez votre chaîne comme suit:

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

size_t destination_size = sizeof (array2);

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

Cette dernière ligne est réellement importante, car strncpy() ne fait pas toujours terminaison nulle chaînes. (Si le tampon de destination est trop petit pour contenir la chaîne source complète, sntrcpy () ne terminera pas nullement la chaîne de destination.)

La page de manuel de strncpy () indique même "Avertissement: s'il n'y a pas d'octet null parmi les n premiers octets de src, la chaîne placée dans dest ne sera pas terminée par la valeur null."

La raison pour laquelle strncpy () se comporte de manière aussi étrange est qu’elle n’était pas conçue à l’origine comme un moyen sûr de copier des chaînes.

Une autre solution consiste à utiliser snprintf () en remplacement sûr de strcpy ():

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

(Merci jxh pour le tuyau.)

22
Prof. Falken

Vous ne pouvez pas affecter de tableaux, les noms sont des constantes qui ne peuvent pas être modifiées.

Vous pouvez copier le conten, avec:

strcpy(array2, array1);

en supposant que la source est une chaîne valide et que la destination est suffisamment grande, comme dans votre exemple.

6
unwind

Comme d'autres l'ont noté, les chaînes sont copiées avec strcpy() ou ses variantes. Dans certains cas, vous pouvez également utiliser snprintf().

Vous pouvez affecter des tableaux comme vous le souhaitez dans le cadre d'une affectation de structure:

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

array2 = array1;

Si vos tableaux sont passés à une fonction, il apparaîtra que vous êtes autorisé à les affecter, mais il ne s'agit que d'un accident de la sémantique. En C, un tableau se décompose en un type de pointeur avec la valeur de l'adresse du premier membre du tableau, et ce pointeur correspond à ce qui est passé. Ainsi, votre paramètre de tableau dans votre fonction est vraiment juste un pointeur. L'affectation est juste une affectation de pointeur:

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

Le tableau lui-même reste inchangé après le retour de la fonction.

Cette sémantique "decay to pointer value" pour les tableaux est la raison pour laquelle l'assignation ne fonctionne pas. La valeur l a le type de tableau, mais la valeur r est le type de pointeur en décomposition, de sorte que l'affectation est entre types incompatibles.

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

Pour expliquer pourquoi la sémantique "decay to pointer value" a été introduite, elle visait à obtenir une compatibilité du code source avec le prédécesseur de C. Vous pouvez lire Le développement du langage C pour plus de détails.

4
jxh

ça devrait ressembler à ça:

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;

n'est pas pris en charge dans c. Vous devez utiliser des fonctions comme strcpy () pour le faire.

1
MOHAMED

c fonctions ci-dessous uniquement ... c ++ vous devez faire tableau de caractères puis utiliser une copie de chaîne puis utiliser les fonctions de tokenizor de chaîne ... c ++ rendait beaucoup plus difficile de faire quoi que ce soit

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

Je recommande d'utiliser memcpy () pour copier des données. De plus, si nous affectons un tampon à un autre comme array2 = array1, les deux tableaux ont la même mémoire et toute modification des déviations arrary1 dans tableau2 aussi. Mais nous utilisons memcpy, les deux tampons ont un tableau différent. Je recommande memcpy () car strcpy et les fonctions associées ne copient pas le caractère NULL.

1
akhil

pour les types entiers

#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

Eh bien, techniquement, vous pouvez…

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

mais ça ne sera pas très beau.

(Oui, le code ci-dessus est accordé pour toujours fonctionner et il est portable)

0
madmurphy

Vous ne pouvez pas assigner de tableaux pour les copier. La façon dont vous pouvez copier le contenu d'un fichier dans un autre dépend de plusieurs facteurs:

Pour les tableaux char, si vous savez que le tableau source est terminé par un caractère nul et que le tableau de destination est suffisamment grand pour que la chaîne du tableau source, y compris le terminateur null, utilisez strcpy():

#include <string.h>

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

...

strcpy(array2, array1);

Si vous ne savez pas si le tableau de destination est suffisamment grand, mais que la source est une chaîne C et que vous voulez que la destination soit une chaîne C appropriée, utilisez snprinf():

#include <stdio.h>

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

...

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

Si le tableau source n'est pas nécessairement terminé à zéro, mais que vous savez que les deux tableaux ont la même taille, vous pouvez utiliser memcpy:

#include <string.h>

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

...

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