2011-10-24 8 views
5

Tengo una matriz de 8 bytes en mi aplicación con estos datos:La conversión de una matriz de bytes C para un largo tiempo

00000133339e36a2 

Estos datos representan un largo (en la plataforma se escribieron los datos en, en una Mac esto sería un largo tiempo) con el valor de

1319420966562 

En la aplicación real que esto es un conjunto semi-aleatoria de los datos, por lo que el número siempre será diferente. Por lo tanto, necesito convertir la matriz de bytes en una larga para imprimir.

He tratado de fundición de los datos directamente en un largo tiempo, pero se me ocurrió

1305392 

donde debería haber estado viendo el número anterior.

Para aquellos de ustedes con más experiencia en la manipulación de C byte que yo, ¿cómo podría convertir correctamente una matriz de bytes a una larga larga?

EDITAR: Extrañamente, todas sus soluciones siguen produciendo el mismo número: 866006690. Ese es el equivalente decimal de los últimos cuatro bytes de los datos.

Respuesta

1
long long num = 0; 
for(int i = 0; i < 8; i++) { 
    num = (num << 8) | byte_array[i]; 
} 

Suponiendo que se almacenan big-endian.

2

En función de su orden de bits deseada, algo como esto funcionaría:

int i; 
char inArray[8] = { 0x00,0x00,0x01,0x33,0x33,0x9e,0x36,0xa2 }; 
long long outLong = 0; 

for(i=0; i<8; i++) 
    outLong |= ((long long)inArray[i]) << (i*8)); 
+0

Y = no es el operador aquí. y la matriz contiene valores hexadecimales. –

+0

Sí, noté al operador y lo solucioné. Y parece que malinterpreté la pregunta. Arreglando eso también, gracias. – Chriszuma

3

Esto parece una de las situaciones (raros), donde una unión es útil:

union number 
{ 
    char charNum[16]; 
    long long longNum; 
}; 
3
union le_long_long_array_u 
{ 
    uint8_t byte[8]; 
    uint64_t longlong; 
} le_long_long_array; 

Copiar (o simplemente use) le_long_long_array.byte[] para la matriz; de lectura de retorno le_long_long_array.longlong

Por ejemplo:

fill_array(&le_long_long_array.byte[0]); 
return le_long_long_array.longlong; 

ejemplo Fuller:

#include <stdint.h> 
#include <stdio.h> 

union le_long_long_array_u 
{ 
    uint8_t byte[8]; 
    uint64_t longlong; 
} le_long_long_array; 

static uint8_t hex2int (char c) 
{ 
    return (c >= '0' && c <= '9') 
      ? (uint8_t)(c - '0') 
      : ((c >= 'a' && c <= 'f') 
       ? (uint8_t)(c - 'a') 
       : ((c >= 'A' && c <= 'F') 
        ? (uint8_t)(c - 'A') 
        : 0)); 
} 

int main (int argc, char **argv) 
{ 
    if (argc == 2) 
    { 
     int i; 
     for (i = 0; i <= 7; i++) 
     { 
      char *str = argv[1]; 

      if (str[2*i] == '\0' || str[2*i+1] == '\0') 
      { 
       printf("Got short string.\n"); 
       return 1; 
      } 

      le_long_long_array.byte[i] = (hex2int(str[2*i]) << 4) + hex2int(str[2*i+1]); 
     } 
     printf("Got %lld\n", le_long_long_array.longlong); 
    } 
    else 
    { 
     printf("Got %d args wanted 1.\n", argc - 1); 
     return 1; 
    } 
    return 0; 
} 

Produce:

e e$ gcc -c un.c 
e e$ gcc -o un un.o 
e e$ ./un 0100000000000000 
Got 1 
e e$ ./un 0101000000000000 
Got 257 
e e$ ./un a23639333301000000 
Got 1319414347266 
e e$ 

como se puede esperar de los datos endian pequeños.

+0

Tenga en cuenta el carácter endógeno, pero no sé cuán grande es realmente esa preocupación. –

+0

Sí, utilicé el prefijo le_ porque la Mac es Little Endian desde x86, aunque en este caso la responsabilidad depende realmente del usuario de la estructura para completar la matriz de bytes de manera apropiada. –

+0

Intenté esto, y terminé con el número 866006690. ¿Alguna idea? – voidzm

1

¡Una gran pregunta! ¡Y excelentes respuestas! Para tirar un centavo:

// Getting stuff "in" 
unsigned long long ll1 = 1319420966562; 
unsigned char * c = reinterpret_cast<unsigned char *>(&ll1); 

// Getting stuff "out" 
unsigned long long ll2; 
memcpy(&ll2, c, 8); 

ll2 es ahora igual a ll1.

Debo administrar, sin embargo, me gustan los ejemplos union mejor. :)

0

¿Quizás una notación de puntero?

uint8_t Array[8] = { 0x00,0x00,0x01,0x33,0x33,0x9e,0x36,0xa2 }; 
uint32_t *Long = Array; 

O si es posible

*((uint32_t*)Array) 
Cuestiones relacionadas