Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

408
Views
printf agrega `FFFFFF` adicional a la impresión hexadecimal de una matriz de caracteres

Considere el siguiente código simplificado a continuación. Quiero extraer algunos datos/secuencias binarias de un archivo e imprimirlo en la salida estándar en formato hexadecimal.

Obtuve 3 bytes adicionales 0xFFFFFF . ¿Qué ocurre? ¿De dónde vienen los bytes extra?

producción

 in: 2000FFFFFFAF00690033005A00 out: 2000FFFFFFAF00690033005A00

programa.c

 #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { int i; char raw[10] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0x00}; FILE *outfile; char *buf; printf("in:\n\t"); for( i=0; i<10; i++ ) printf("%02X", raw[i]); outfile = fopen("raw_data.bin", "w+b"); fwrite(raw, 1, 10, outfile); buf = (char *) malloc (32 * sizeof(char)); fseek(outfile, 0, SEEK_SET); fread(buf, 1, 10, outfile); printf("\nout:\n\t"); for( i=0; i<10; i++ ) printf("%02X", buf[i]); printf("\n"); fclose(outfile); return 0; }
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Extensión de signo. Su compilador está implementando char como un signed char . Cuando pasa los caracteres a printf , todos se extienden durante su promoción a int s. Cuando el primer bit es un 0 esto no importa, porque se extiende con 0 s.

0xAF en binario es 10101111 Dado que el primer bit es un 1 , al pasarlo a printf se extiende con todos los 1 en la conversión a int , lo que lo convierte en 11111111111111111111111110101111 , el valor hexadecimal que tiene.

Solución: use unsigned char (en lugar de char ) para evitar que se produzca la extensión de la señal en la llamada

 const unsigned char raw[] = {0x20,0x00,0xAF,0x00,0x69,0x00,0x33,0x00,0x5A,0x00};

Todos estos valores en su ejemplo original se están extendiendo, solo que 0xAF es el único con un 1 en el primer bit.

Otro ejemplo más simple del mismo comportamiento ( enlace en vivo ):

 signed char c = 0xAF; // probably gives an overflow warning int i = c; // extra 24 bits are all 1 assert( i == 0xFFFFFFAF );
over 4 years ago · Santiago Trujillo Report

0

Esto se debe a que 0xAF cuando se convierte de un carácter con signo a un entero con signo es negativo (es un signo extendido), y el formato %02X es para argumentos sin signo e imprime el valor convertido como FFFFFFAF .

Los caracteres adicionales aparecen porque printf %x nunca truncará silenciosamente los dígitos de un valor. Los valores que no son negativos también obtienen un signo extendido, pero eso es solo agregar cero bits y el valor cabe en 2 dígitos hexadecimales, por lo que printf %02 puede funcionar con una salida de dos dígitos.

Tenga en cuenta que hay 2 dialectos de C: uno en el que se firma el char simple y otro en el que no está firmado. En el tuyo está firmado. Puede cambiarlo usando una opción, por ejemplo, gcc y clang support -funsigned-char and -fsigned-char .

over 4 years ago · Santiago Trujillo Report

0

printf() es una función variable y sus argumentos adicionales (correspondientes a ... parte de su prototipo) están sujetos a las promociones de argumento predeterminadas , por lo que char se promociona a int .

Como su char ha firmado 1 , la representación del complemento de dos, el bit más significativo se establece en uno para el elemento 0xAF . Durante la promoción, se propaga el bit firmado, lo que da como resultado 0xFFFFFFAF de tipo int , como presumiblemente sizeof(int) = 4 en su implementación.

Por cierto, está invocando un comportamiento indefinido , ya que el especificador de formato %X debe usarse para objetos de tipo unsigned int o al menos para int con MSB que no está configurado (esta es una práctica común y ampliamente aceptada).

Como se sugirió, puede considerar el uso de un tipo de unsigned char inequívoco.


1) La ejecución puede elegir entre la representación firmada y no firmada de char . Es bastante común que char esté firmado, pero no puedes darlo por sentado para todos los demás compiladores del planeta. Algunos de ellos pueden permitir elegir entre estos dos modos, como se menciona en la respuesta de Jens .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!