c++ - texto - sql server data type table
¿Cómo imprimo bytes como hexadecimal? (6)
Imprimiendo estructuras arbitrarias en el moderno C ++
Hasta ahora, todas las respuestas solo le indican cómo imprimir una matriz de enteros, pero también podemos imprimir cualquier estructura arbitraria, dado que sabemos su tamaño. El siguiente ejemplo crea dicha estructura e itera un puntero a través de sus bytes, imprimiéndolos en la salida:
#include <iostream>
#include <iomanip>
#include <cstring>
using std::cout;
using std::endl;
using std::hex;
using std::setfill;
using std::setw;
using u64 = unsigned long long;
using u16 = unsigned short;
using f64 = double;
struct Header {
u16 version;
u16 msgSize;
};
struct Example {
Header header;
u64 someId;
u64 anotherId;
bool isFoo;
bool isBar;
f64 floatingPointValue;
};
int main () {
Example example;
// fill with zeros so padding regions don''t contain garbage
memset(&example, 0, sizeof(Example));
example.header.version = 5;
example.header.msgSize = sizeof(Example) - sizeof(Header);
example.someId = 0x1234;
example.anotherId = 0x5678;
example.isFoo = true;
example.isBar = true;
example.floatingPointValue = 1.1;
cout << hex << setfill(''0''); // needs to be set only once
auto *ptr = reinterpret_cast<unsigned char *>(&example);
for (int i = 0; i < sizeof(Example); i++, ptr++) {
if (i % sizeof(u64) == 0) {
cout << endl;
}
cout << setw(2) << static_cast<unsigned>(*ptr) << " ";
}
return 0;
}
Y aquí está la salida:
05 00 24 00 00 00 00 00
34 12 00 00 00 00 00 00
78 56 00 00 00 00 00 00
01 01 00 00 00 00 00 00
9a 99 99 99 99 99 f1 3f
Note que este ejemplo también ilustra el funcionamiento de la alineación de la memoria . Vemos una version
ocupa 2 bytes ( 05 00
), seguida de msgSize
con 2 bytes más ( 24 00
) y luego 4 bytes de relleno, después de lo cual aparece un poco de someId
( 34 12 00 00 00 00 00 00
) y otro anotherId
( 78 56 00 00 00 00 00 00
). Luego, isFoo
, que ocupa 1 byte ( 01
) e isBar
, otro byte ( 01
), seguido de 6 bytes de relleno, y finalmente termina con la representación estándar IEEE 754 del doble campo floatingPointValue
.
También tenga en cuenta que todos los valores se representan como little endian (los bytes menos significativos vienen primero), ya que se compilaron y ejecutaron en una plataforma Intel.
Sé que en C # puedes usar el método String.Format. ¿Pero cómo haces esto en C ++? ¿Hay alguna función que me permita convertir un byte en un hex? Solo necesito convertir un dato largo de 8 bytes a Hex, ¿cómo hago eso?
Bueno, puede convertir un byte (carácter sin signo) a la vez en una matriz como tal
char buffer [17];
buffer[16] = 0;
for(j = 0; j < 8; j++)
sprintf(&buffer[2*j], "%02X", data[j]);
DO:
static void print_buf(const char *title, const unsigned char *buf, size_t buf_len)
{
size_t i = 0;
fprintf(stdout, "%s/n", title);
for(i = 0; i < buf_len; ++i)
fprintf(stdout, "%02X%s", buf[i],
( i + 1 ) % 16 == 0 ? "/r/n" : " " );
}
C ++:
void print_bytes(std::ostream& out, const char *title, const unsigned char *data, size_t dataLen, bool format = true) {
out << title << std::endl;
out << std::setfill(''0'');
for(size_t i = 0; i < dataLen; ++i) {
out << std::hex << std::setw(2) << (int)data[i];
if (format) {
out << (((i + 1) % 16 == 0) ? "/n" : " ");
}
}
out << std::endl;
}
Esta es una versión modificada del método Nibble to Hex
void hexArrayToStr(unsigned char* info, unsigned int infoLength, char **buffer) {
const char* pszNibbleToHex = {"0123456789ABCDEF"};
int nNibble, i;
if (infoLength > 0) {
if (info != NULL) {
*buffer = (char *) malloc((infoLength * 2) + 1);
buffer[0][(infoLength * 2)] = 0;
for (i = 0; i < infoLength; i++) {
nNibble = info[i] >> 4;
buffer[0][2 * i] = pszNibbleToHex[nNibble];
nNibble = info[i] & 0x0F;
buffer[0][2 * i + 1] = pszNibbleToHex[nNibble];
}
} else {
*buffer = NULL;
}
} else {
*buffer = NULL;
}
}
No conozco una manera mejor que:
unsigned char byData[xxx];
int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
sprintf(pBuffer[2 * i], "%02X", byData[i]);
}
Puedes acelerarlo usando el método Nibble to Hex
unsigned char byData[xxx];
const char szNibbleToHex = { "0123456789ABCDEF" };
int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
// divide by 16
int nNibble = byData[i] >> 4;
pBuffer[2 * i] = pszNibbleToHex[nNibble];
nNibble = byData[i] & 0x0F;
pBuffer[2 * i + 1] = pszNibbleToHex[nNibble];
}
Si desea utilizar secuencias de C ++ en lugar de funciones de C, puede hacer lo siguiente:
int ar[] = { 20, 30, 40, 50, 60, 70, 80, 90 };
const int siz_ar = sizeof(ar) / sizeof(int);
for (int i = 0; i < siz_ar; ++i)
cout << ar[i] << " ";
cout << endl;
for (int i = 0; i < siz_ar; ++i)
cout << hex << setfill(''0'') << setw(2) << ar[i] << " ";
cout << endl;
Muy simple.
Salida:
20 30 40 50 60 70 80 90
14 1e 28 32 3c 46 50 5a