38 votes

C tableau codé en dur en tant que paramètre memcpy

Je veux passer une codé en dur char tableau comme l' source paramètre de memcpy ... quelque Chose comme ceci:

memcpy(dest, {0xE3,0x83,0xA2,0xA4,0xCB} ,5);

Cette compilé avec clang donne l'erreur suivante:

cccc.c:28:14: error: expected expression

Si je le modifier (voir la parenthèse supplémentaires ):

memcpy(dest,({0xAB,0x13,0xF9,0x93,0xB5}),5);

l'erreur donnée par clang est:

cccc.c:26:14: warning: incompatible integer to pointer
              conversion passing 'int' to parameter of
              type 'const void *' [-Wint-conversion]

cccc.c:28:40: error: expected ';' after expression
memcpy(c+110,({0xAB,0x13,0xF9,0x93,0xB5}),5);

Donc, la question:

Comment puis-je passer une codé en dur tableau comme paramètre source d' memcpy (http://www.cplusplus.com/reference/cstring/memcpy/)

J'ai essayé:

(void*)(&{0xAB,0x13,0xF9,0x93,0xB5}[0])  - syntax error
{0xAB,0x13,0xF9,0x93,0xB5}               - syntax error
({0xAB,0x13,0xF9,0x93,0xB5})             - see above
(char[])({0xE3,0x83,0xA2,0xA4,0xCB})     - error: cast to incomplete type 'char []' (clang)

et un peu plus fou des combinaisons, je suis la honte de l'écrire ici ...

Rappelez-vous: je n'ai PAS envie de créer une nouvelle variable pour contenir le tableau.

41voto

MikeCAT Points 3205

Si vous utilisez C99 ou version ultérieure, vous pouvez utiliser le composé de littéraux. (N1256 6.5.2.5)

#include <stdio.h>
#include <string.h>
int main(void){
    char dest[5] = {0};
    memcpy(dest, (char[]){0xE3,0x83,0xA2,0xA4,0xCB} ,5);
    for (int i = 0; i < 5; i++) printf("%X ", (unsigned int)(unsigned char)dest[i]);
    putchar('\n');
    return 0;
}

Mise à JOUR: il a travaillé pour C++03 et C++11 sur GCC, mais sont rejetés avec -pedantic-errors option. Cela signifie que ce n'est pas une solution valable pour la norme C++.

#include <cstdio>
#include <cstring>
int main(void){
    char dest[5] = {0};
    memcpy(dest, (const char[]){(char)0xE3,(char)0x83,(char)0xA2,(char)0xA4,(char)0xCB} ,5);
    for (int i = 0; i < 5; i++) printf("%X ", (unsigned int)(unsigned char)dest[i]);
    putchar('\n');
    return 0;
}

des points sont les suivants:

  • Vérifiez le tableau const, ou de prendre l'adresse de tableau temporaire sera rejetée.
  • Cast numéros char explicitement, ou le rétrécissement de conversion sera rejetée.

24voto

Igal S. Points 2338

Vous pouvez simplement envoyer une chaîne en tant que paramètre. Il semble bien se compiler.

 #include <iostream>
#include <string.h>
using namespace std;

int main() {
    char dest[6] = {0};
    memcpy(dest,"\XAB\x13\XF9\X93\XB5", 5);

    return 0;
}
 

18voto

Lundin Points 21616

La meilleure solution est de ne pas le faire du tout, mais d'utiliser une variable temporaire:

const char src[] = {0xE3,0x83,0xA2,0xA4,0xCB};
memcpy(dest, src, sizeof(src));

Ce code est le plus facile à gérer, car il ne contient pas "nombres magiques", de sorte qu'il ne contient aucune manquant élément de tableau ou d'une matrice (hors des limites de bugs, comme le composé version littérale pourrait.

Ce code est également compatible avec le C++ et C90.

La chose la plus importante ici est de réaliser que le code machine généré sera le même de toute façon. Ne pensez pas que vous faites n'importe quel forme d'optimisation en utilisant le composé de littéraux.

10voto

LPs Points 2090

Vous pouvez utiliser des littéraux composés .

 int main()
{
    unsigned char dest[5];
    size_t i;

    memcpy(dest, (unsigned char[]){0xE3,0x83,0xA2,0xA4,0xCB} ,5);

    printf("Test: " );
    for(i=0; i<sizeof(dest)/sizeof(dest[0]); i++)
        printf("%02X - ", dest[i] );
    printf("\n");
    return 0;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X