C SSCANF ("% HHX") Lea un INT sin firmar en lugar de char -- ampo con scanf camp Relacionados El problema

C sscanf(“%hhx”) read an unsigned int instead of unsigned char


1
vote

problema

Español

Utilizamos el SSCANF () para convertir el valor hexadecimal para cadena de la siguiente manera:

  [{"docentnaam":"Alex"},{"docentnaam":"Jos"},{"docentnaam":"Dick"},{"docentnaam":"Annemarije"},{"docentnaam":"Martijn"},{"docentnaam":"John"},{"docentnaam":"Bart"},{"docentnaam":"Bart"},{"docentnaam":"Peter"},{"docentnaam":"Dietske"},{"docentnaam":"Peter"}]111  

Salida:

  [{"docentnaam":"Alex"},{"docentnaam":"Jos"},{"docentnaam":"Dick"},{"docentnaam":"Annemarije"},{"docentnaam":"Martijn"},{"docentnaam":"John"},{"docentnaam":"Bart"},{"docentnaam":"Bart"},{"docentnaam":"Peter"},{"docentnaam":"Dietske"},{"docentnaam":"Peter"}]2  

Desde la primera salida, podemos ver que [{"docentnaam":"Alex"},{"docentnaam":"Jos"},{"docentnaam":"Dick"},{"docentnaam":"Annemarije"},{"docentnaam":"Martijn"},{"docentnaam":"John"},{"docentnaam":"Bart"},{"docentnaam":"Bart"},{"docentnaam":"Peter"},{"docentnaam":"Dietske"},{"docentnaam":"Peter"}]3 lee los 4 bytes completos en lugar de 1 byte ("Char no signo"). ¿Por qué?

Original en ingles

We use the sscanf() to convert hexadecimal value to string as follows:

#include <stdio.h> #include <string> int main() {     char data[] = "41424344";     unsigned int result = 0;     sscanf(data, "%hhx", &result);     printf("%x\n", result);     result = 0;     sscanf(data, "%2x", &result);     printf("%x\n", result);     result = 0;     sscanf(data, "%2hhx", &result);     printf("%x\n", result);     return 0; } 

output:

41424344 41 41 

From the first output, we can see that sscanf("%hhx") read the whole 4 bytes instead of 1 byte ("unsigned char"). why?

     
     
     

Lista de respuestas

4
 
vote

comportamiento indefinido debido al especificador de formato desajustado y el tipo de argumento.

de acuerdo con por ejemplo. este 99887776621 Referencia El certutil.exe2 < / Código> Prefijo significa que el argumento debe ser un certutil.exe3 , que es totalmente diferente del .key24 que pasa.

En realidad, tiene este problema con el formato .key25 también.

 

Undefined Behaviour because of mismatched format specifier and argument type.

According to e.g. this scanf reference the hh prefix means that the argument needs to be an unsigned char *, which is totally different from the unsigned int * you pass.

You actually have this problem with the %2hhx format as well.

 
 
0
 
vote

Utilizamos el SSCANF () para convertir el valor hexadecimal para cadena de la siguiente manera:

Bueno, su código es todo menos un convertidor entre hexadecimal a cadena. Su código solo acepta una cadena, e intenta emitir algo en función de la conversión de los caracteres interpretados como números hexadecimales. Entonces, si me limito al primer párrafo anterior, una solución simple para eso sería:

  #include <stdio.h>  char *toHexString(         unsigned value, /* the value to be converted */         char *buffer,   /* the char buffer to hold the converted data. */         size_t buf_size)/* the size of the previous buffer */ {     if (!buf_size) return NULL; /* error, no space in buffer */     char *p = buffer + buf_size; /* start at the end of buffer */     *--p = ''; /* the string terminator, we go backwards */     while (value && p > buffer) {         *--p = "0123456789abcdef"[value & 0xf];         value >>= 4;     }     if (value && p == buffer) { /* overflow */         return NULL;     }     return p; }  int main() {     char buffer[20];      /* we should call first the function, to check for NULL      * return value, but we know a priori that an unsigned      * int will be less than 20 digits (including the final      * null char), so we don't need to check for NULL      * return.      */     puts(toHexString(0x12389abcU, buffer, sizeof buffer)); }   

Perdón por ignorar completamente su código, pero como lo escribió nada, ni siquiera se aproxime a lo que pretende, convertir un número hexagonal (utilizo un código hexadecimal 9988777661 literal 0x12389abcU ) e imprima la cadena (que está en el puntero devuelto por toHexString() ).


Note

  • Su código no compila con los parámetros de compilador predeterminados. Da los siguientes dos errores:
  pru2.c: In function ‘main’: pru2.c:7:22: error: format ‘%hhx’ expects argument of type ‘unsigned char *’, but argument 3 has type ‘unsigned int *’ [-Werror=format=]     7 |     sscanf(data, "%hhx", &result);       |                   ~~~^   ~~~~~~~       |                      |   |       |                      |   unsigned int *       |                      unsigned char *       |                   %x pru2.c:13:23: error: format ‘%hhx’ expects argument of type ‘unsigned char *’, but argument 3 has type ‘unsigned int *’ [-Werror=format=]    13 |     sscanf(data, "%2hhx", &result);       |                   ~~~~^   ~~~~~~~       |                       |   |       |                       |   unsigned int *       |                       unsigned char *       |                   %2x cc1: all warnings being treated as errors *** Error code 1   

Si lo compilo usando --std=c89 , esos errores se convierten en solo advertencias y permite obtener un ejecutable:

  lcu@titan:~/git/cornucopia$ make CFLAGS='--std=c89' pru2 cc --std=c89   -o pru2 pru2.c  pru2.c: In function ‘main’: pru2.c:7:22: warning: format ‘%hhx’ expects argument of type ‘unsigned char *’, but argument 3 has type ‘unsigned int *’ [-Wformat=]     7 |     sscanf(data, "%hhx", &result);       |                   ~~~^   ~~~~~~~       |                      |   |       |                      |   unsigned int *       |                      unsigned char *       |                   %x pru2.c:13:23: warning: format ‘%hhx’ expects argument of type ‘unsigned char *’, but argument 3 has type ‘unsigned int *’ [-Wformat=]    13 |     sscanf(data, "%2hhx", &result);       |                   ~~~~^   ~~~~~~~       |                       |   |       |                       |   unsigned int *       |                       unsigned char *       |                   %2x   

Pero después de compilar, obtengo una salida completamente diferente:

  lcu@titan:~/git/cornucopia$ pru2 44 41 41   

que no es lo que usted indique en su pregunta. Por cierto, tuve que reparar un #include <string> en #include <string.h> . (¿Probablemente estás compilando este código con un compilador C ++?)

Por esta y otras razones, le recomiendo que lea Cómo crear un ejemplo mínimo y reproducible y una vez Lo has leído, Publica tu pregunta con un código que realmente muestra lo que dice. Si crees que tenemos algo de magia para adivinar lo que pretendas, ¿qué has probado, y también tenemos que corregir su Escribiendo errores en su publicación, perdemos mucho tiempo con su pregunta, y eso es probablemente bueno para usted, porque aprende mucho ... pero es horrible para otras personas las que exigen ayuda. Las normas y la documentación son para leer ... No por pedirle aquí para que alguien les esté leyendo.

La próxima vez que publique una pregunta. Por favor, pruebe el código de muestra que va a enviar, solo para verificar que no le otorgue nuevos errores y advertencias que no estén en sus casos de prueba. Y una vez que haya probado el código, copie y péguelo como sea, con todos los archivos de inclusión y todo lo necesario para que nos compile y pruebe si necesitamos proporcionar todo lo que obtiene por no ser necesario, Puede ocultar el error en el código no aproximado, y no veremos nada extraño, sino muchos errores de escritura.

 

We use the sscanf() to convert hexadecimal value to string as follows:

Well, your code is everything but a converter between hexadecimal to string. Your code just accepts a string, and tries to output somewhat based on the conversion of the interpreted characters as hexadecimal numbers. So, If I tie myself to the first paragraph above, a simple solution to that would be:

#include <stdio.h>  char *toHexString(         unsigned value, /* the value to be converted */         char *buffer,   /* the char buffer to hold the converted data. */         size_t buf_size)/* the size of the previous buffer */ {     if (!buf_size) return NULL; /* error, no space in buffer */     char *p = buffer + buf_size; /* start at the end of buffer */     *--p = '\0'; /* the string terminator, we go backwards */     while (value && p > buffer) {         *--p = "0123456789abcdef"[value & 0xf];         value >>= 4;     }     if (value && p == buffer) { /* overflow */         return NULL;     }     return p; }  int main() {     char buffer[20];      /* we should call first the function, to check for NULL      * return value, but we know a priori that an unsigned      * int will be less than 20 digits (including the final      * null char), so we don't need to check for NULL      * return.      */     puts(toHexString(0x12389abcU, buffer, sizeof buffer)); } 

Sorry for ignoring completely your code, but as written it does nothing, even approximate to what you pretend, converting an hex number (I use an hexadecimal unsigned int literal 0x12389abcU) and print the string (which is in the pointer returned by toHexString()).


Note

  • Your code doesn't compile with the default compiler parameters. It gives the following two errors:
pru2.c: In function xe2x80x98mainxe2x80x99: pru2.c:7:22: error: format xe2x80x98%hhxxe2x80x99 expects argument of type xe2x80x98unsigned char *xe2x80x99, but argument 3 has type xe2x80x98unsigned int *xe2x80x99 [-Werror=format=]     7 |     sscanf(data, "%hhx", &result);       |                   ~~~^   ~~~~~~~       |                      |   |       |                      |   unsigned int *       |                      unsigned char *       |                   %x pru2.c:13:23: error: format xe2x80x98%hhxxe2x80x99 expects argument of type xe2x80x98unsigned char *xe2x80x99, but argument 3 has type xe2x80x98unsigned int *xe2x80x99 [-Werror=format=]    13 |     sscanf(data, "%2hhx", &result);       |                   ~~~~^   ~~~~~~~       |                       |   |       |                       |   unsigned int *       |                       unsigned char *       |                   %2x cc1: all warnings being treated as errors *** Error code 1 

If I compile it using --std=c89, those errors become just warnings and allows to get an executable:

lcu@titan:~/git/cornucopia$ make CFLAGS='--std=c89' pru2 cc --std=c89   -o pru2 pru2.c  pru2.c: In function xe2x80x98mainxe2x80x99: pru2.c:7:22: warning: format xe2x80x98%hhxxe2x80x99 expects argument of type xe2x80x98unsigned char *xe2x80x99, but argument 3 has type xe2x80x98unsigned int *xe2x80x99 [-Wformat=]     7 |     sscanf(data, "%hhx", &result);       |                   ~~~^   ~~~~~~~       |                      |   |       |                      |   unsigned int *       |                      unsigned char *       |                   %x pru2.c:13:23: warning: format xe2x80x98%hhxxe2x80x99 expects argument of type xe2x80x98unsigned char *xe2x80x99, but argument 3 has type xe2x80x98unsigned int *xe2x80x99 [-Wformat=]    13 |     sscanf(data, "%2hhx", &result);       |                   ~~~~^   ~~~~~~~       |                       |   |       |                       |   unsigned int *       |                       unsigned char *       |                   %2x 

but after compiling, I get a completely different output:

lcu@titan:~/git/cornucopia$ pru2 44 41 41 

which is not what you state in your question. By the way, I had to repair a #include <string> into #include <string.h> previous error. (are you probably compiling this code with a c++ compiler?)

For this and other reasons, I recommend you to read How to create a Minimal, Reproducible Example and once you have read it, post your question with a code that actually shows what you say. If you think we have some magic to guess what you intend, what have you tried, and we have also to correct your typing mistakes on your post, we lose a lot of time with your question, and that's probably good for you, because you learn a lot... but it is horrible for other people that demand help. Norms and documentation are for being read... not for asking here to get somebody reading them for you.

Next time you post a question. Please, test the sample code you are going to send, just to check that it doesn't give new errors and warnings that weren't in your testing cases. And ONCE YOU HAVE TESTED THE CODE, COPY AND PASTE IT AS IT IS, WITH ALL THE INCLUDE FILES AND EVERYTHING NECESSARY FOR US TO COMPILE AND TEST If we need to provide everything you get for not needed, you can hide the error in the unposted code, and we'll see nothing strange, but a lot of typing mistakes.

 
 

Relacionados problema

10  ¿Por qué SCANF ("% d", [...]) no consume ' n'? Mientras que SCANF ("% C") hace?  ( Why scanfd does not consume n while scanfc does ) 
aquí , vi esta declaración en la respuesta aceptada: La mayoría de los especificadores de conversión Omiten espacios en blanco líderes, incluidas las reci...

-8  ¿Cómo clasifica algo en la misma línea de texto en C [cerrado]  ( How do you type something on the same line of text in c ) 
cerrado. Esta pregunta necesita Detalles de depuración . Actualmente no está aceptando respuestas. ...

0  No se puede tomar entrada en una cadena  ( Cant take input in a string ) 
En este programa, no puedo obtener la entrada en la cadena C [] (en ADD_DIARY ()) mediante el uso de fgets () o obtiene (), el programa simplemente salta el p...

3  Copiando enteros en una matriz usando FSCANF (). C ª  ( Copying integers into an array using fscanf in c ) 
Tengo un archivo con varias filas de 10 enteros. Quiero copiar esos enteros en varias matrices, llamada Line1, Line2, Line3, etc. con números de cada fila e...

9  Valor de devolución FSCANF  ( Fscanf return value ) 
¿Qué retorna FSCANF cuando lee los datos en el archivo? Por ejemplo, int number1, number2, number3, number4, c; c = fscanf (spFile, "%d", &number1); //c w...

0  My FSCANF emite un gran número negativo  ( My fscanf outputs a large negative number ) 
En este programa, estoy intentando leer un nombre y su GPA de un archivo. El primer nombre es Audrey, luego un espacio en blanco, y luego 3.6. La segunda líne...

11  ¿Cómo convertir por lo contrario una cadena en un tipo de entero poco común?  ( How to portably convert a string into an uncommon integer type ) 
Algunos antecedentes: Si quería usarlo, por ejemplo, scanf() para convertir una cadena en un tipo de entero estándar, como uint16_t , usaría SCNu16 a par...

1  C: Formato% S espera argumento de tipo char * en un programa de cuerdas divertidas  ( C format s expects argument of type char in funny strings program ) 
Estoy haciendo un programa para verificar las cuerdas divertidas. Para entender el ejercicio Lea esto . Mi código está aquí: #define MAX_STR_LENGTH 10 ...

0  Lectura e impresión desde un archivo pero atascado en el bucle c  ( Reading and printing from a file but stuck in loop c ) 
Estoy tratando de leer algunos datos de un archivo y luego imprimirlo, pero mi código solo está leyendo el primer contenido y luego se atasca en un bucle infi...

3  VIM HACE CREA nuevo archivo con QuickFIX - ERRORFORMAT  ( Vim make creates new file with quickfix errorformat ) 
Esto parece ser causado por el error de error que está equivocado, pero no estoy seguro de lo que está causando que mira el valor actual. Resultado de test...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos