web-dev-qa-db-fra.com

Copier struct dans struct en C

Je veux copier une structure identique dans une autre et l’utiliser plus tard comme comparaison. Le fait est que mon compilateur me donne un avertissement quand je fais comme ça! Devrais-je le faire d'une autre manière ou est-ce que je le fais mal:

Dans l'en-tête Fichier:

extern struct RTCclk
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t mday;
uint8_t month;
uint8_t year;
}
RTCclk;

En fichier C:

struct RTCclk RTCclk;
struct RTCclk RTCclkBuffert;

void FunctionDO(void)
{
   ... // Some Code
   /* Copy first struct values into the second one */
   memcpy(&RTCclk, &RTCclkBuffert, sizeof RTCclk);
}
52
Christian

Pour les structures simples, vous pouvez utiliser memcpy comme vous le faites ou simplement affecter de l'une à l'autre:

RTCclk = RTCclkBuffert;

Le compilateur créera du code pour copier la structure pour vous.


Une remarque importante à propos de la copie: c'est une copie superficielle, comme avec memcpy. Cela signifie que si vous avez par exemple une structure contenant des pointeurs, seuls les pointeurs réels seront copiés et non pas ce qu’ils pointent; ainsi, après la copie, deux pointeurs pointant vers la même mémoire.

121

Votre code est correct. Vous pouvez aussi assigner l'un à l'autre directement (voir Réponse de Joachim Pileborg ).

Plus tard, lorsque vous comparez les deux structures, vous devez faire attention à comparer les structures le long chemin, membre par membre, au lieu d'utiliser memcmp; voir Comment comparez-vous les structures pour l'égalité en C?

18
Graham Borland

copiez la structure en c il vous suffit d’attribuer les valeurs comme suit: 

struct RTCclk RTCclk1;
struct RTCclk RTCclkBuffert;

RTCclk1.second=3;
RTCclk1.minute=4;
RTCclk1.hour=5;

RTCclkBuffert=RTCclk1;

maintenant RTCclkBuffert.hour aura la valeur 5,

RTCclkBuffert.minute aura la valeur 4

RTCclkBuffert.second aura la valeur 3

2
Hemant Metalia

memcpy s'attend à ce que les deux premiers arguments soient nuls *.

Essayez: memcpy( (void*)&RTCclk, (void*)&RTCclkBuffert, sizeof(RTCclk) );

P.S. bien que cela ne soit pas nécessaire, la convention dicte les crochets pour l'opérateur sizeof. Vous pouvez vous en tirer avec beaucoup de choses en C qui rendent le code impossible à maintenir. Suivre les conventions est donc la marque d'un bon programmeur C (utilisable).

1
Dan

Aussi un bon exemple ..... 

struct point{int x,y;};
typedef struct point point_t;
typedef struct
{
    struct point ne,se,sw,nw;
}rect_t;
rect_t temp;


int main()
{
//rotate
    RotateRect(&temp);
    return 0;
}

void RotateRect(rect_t *givenRect)
{
    point_t temp_point;
    /*Copy struct data from struct to struct within a struct*/
    temp_point = givenRect->sw;
    givenRect->sw = givenRect->se;
    givenRect->se = givenRect->ne;
    givenRect->ne = givenRect->nw;
    givenRect->nw = temp_point;
}
1
newrev426

Votre code memcpy est correct.

À mon avis, il manque une inclusion de string.h. Donc, le compilateur suppose un prototype incorrect de memcpy et donc l'avertissement.

Quoi qu'il en soit, vous devriez simplement assigner les structures par souci de simplicité (comme l'a souligné Joachim Pileborg).

1
undur_gongor

Je pense que vous devriez lancer les pointeurs sur (vide *) pour vous débarrasser des avertissements.

memcpy((void *)&RTCclk, (void *)&RTCclkBuffert, sizeof RTCclk);

Vous pouvez aussi utiliser sizeof sans crochets, vous pouvez l’utiliser avec des variables, mais si RTCclk était défini comme un tableau, sizeof of retournera la taille complète du tableau. Si vous utilisez sizeof avec le type, vous devez utiliser des crochets.

sizeof(struct RTCclk)
0
Alpha