2010-01-29 17 views
7

Puedo hacer esto:Conseguir un número hexadecimal en un programa a través de la línea de comandos

int main(int argc, char** argv) { 
    unsigned char cTest = 0xff; 
    return 0; 
} 

Pero ¿cuál es la manera correcta para obtener un número hexadecimal en el programa a través de la línea de comandos?

unsigned char cTest = argv[1];

no hace el truco. Eso produce una inicialización que hace un entero desde el puntero sin una advertencia de fundición.

+4

argumentos de línea de comandos son siempre ** ** cuerdas. Algunas plataformas pueden hacer que sean Unicode, en cuyo caso un simple 'strtol' no funcionará. – dirkgently

+0

@dirkgently: ¿en qué caso 'mbstol' o cualesquiera variantes multibyte o wide char (o TCHAR) cubrirían eso? (También dudo que esto sea una preocupación clave dada la naturaleza de la pregunta –

+1

@dirkgently: en ese caso, ¿el segundo parámetro de 'main()' no es de tipo 'char **'? Eso no puede ser compatible con los estándares –

Respuesta

7
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    printf("%ld\n", strtol(argv[1], NULL, 16)); 

    return 0; 
} 

Ejemplo de uso:

$ ./hex ff 
255
7

Usted podría utilizar strtoul que caminar a través de los caracteres en la cadena y convertirlos, teniendo en cuenta la base (16 en este contexto) que se pasa en: -

char *terminatedAt; 
if (argc != 2) 
    return 1; 

unsigned long value = strtoul(argv[1], &terminatedAt, 16); 

if (*terminatedAt != '\0') 
    return 2; 

if (value > UCHAR_MAX) 
    return 3; 

unsigned char byte = (unsigned char)value; 
printf("value entered was: %d", byte); 

como se explica en la otra ejemplos, hay formas más cortas, pero ninguno de ellos le permiten a un error de forma limpia verificar el procesamiento (¿qué ocurre si alguien pasa FFF y sólo tengo una unsiged char para ponerlo en

por ejemplo, con sscanf:?

int val; 
sscanf(argv[1], &val) 
printf("%d\n", val); 
+0

'UCHAR_MAX' puede ser mayor que' LONG_MAX', por lo que deberías usar 'strtoul() ', y' value> 255' debe ser 'value> UCHAR_MAX'. Finalmente,' static_cast' es C++; aquí no necesita un molde debido a las reglas implícitas de conversión. –

+0

Ta, tuve un 'cout' en en la versión inicial: PI pensó en usarlo inicialmente, pero pensó que complicaría demasiado las cosas dado que el que pregunta busca principalmente entender un concepto que no es inmediatamente obvio para ellos. –

+0

Estoy de acuerdo en que a veces uno tiene que hacer cosas que no son del todo -pedante Poco correcto para principiantes, pero en este caso creo que la pedantería no es demasiado difícil, incluso para un principiante. Evitará que muchas personas asuman 'UCHAR_MAX == 255' o' LONG_MAX> UCHAR_MAX', etc. ¡Gracias por la edición y una buena respuesta! –

-3

atoi, atol, strtoi, strtol

todo en stdlib.h

+1

Todo apuntado 3 minutos antes (vea también la página del hombre vinculado) pero no ayuda al que pregunta a entender por qué es necesario ni a dar una muestra. Cuando una publicación no se agrega, es bueno borrarla para mantenerla SECA –

4
unsigned char cTest = argv[1]; 

es incorrecto, porque argv[1] i s del tipo char *. Si argv[1] contiene algo como "0xff" y desea asignar el valor entero correspondiente a un unsigned char, la forma más fácil sería usar strtoul() para convertirlo primero a unsigned long, y luego verificar para ver si el valor convertido es menor que o igual a UCHAR_MAX. En caso afirmativo, puede asignarlo al cTest.

strtoul() El tercer parámetro es una base, que puede ser 0 para designar el análisis del número de estilo C (se permiten literales octales y hexadecimales). Si solo quieres permitir la base 16, pasa eso como el tercer argumento al strtoul(). Si desea permitir que cualquier base (para que pueda analizar 0xff, 0377, 255, etc.), utilice 0.

UCHAR_MAX se define en <limits.h>.

+0

+1 buena explicación, teniendo en cuenta el razonamiento detrás de la mayoría de los puntos que trato de mostrar en el código –

1

La forma tradicional de hacer este tipo de cosas en C es con scanf(). Es exactamente el inverso de printf(), leyendo el formato del archivo (o terminal) y en las variables que lista, en lugar de escribirlas en él.

En su caso, utilizaría sscanf ya que ya lo tiene en una cadena en lugar de una secuencia.

11

Creo que algunas personas que llegan aquí sólo podría estar buscando:

$ ./prog `python -c 'print "\x41\x42\x43"'` 
$ ./prog `perl -e 'print "\x41\x42\x43"'` 
$ ./prog `ruby -e 'print "\x41\x42\x43"'` 
+2

Estaba. ¡Muchas gracias! – Yuka

+0

Gracias cargas - muy, muy útil – TomP89

Cuestiones relacionadas