I can do this:
int main(int argc, char** argv) {
unsigned char cTest = 0xff;
return 0;
}
But what's the right way to get a hexadecimal number into the program via the command line?
unsigned char cTest = argv[1];
doesn't do the trick. That produces a initialization makes integer from pointer without a cast warning.
In C programming language, hexadecimal value is represented as 0x or 0X and to input hexadecimal value using scanf which has format specifiers like %x or %X.
Python hex() function is used to convert an integer to a lowercase hexadecimal string prefixed with “0x”. We can also pass an object to hex() function, in that case the object must have __index__() function defined that returns integer. The input integer argument can be in any base such as binary, octal etc.
Hexadecimal uses the numeric digits 0 through 9 and the letters 'a' through 'f' to represent the numeric values 10 through 15). Each hex digit is directly equivalent to 4 bits. C++ precedes a hexadecimal value that it prints with the characters "0x" to make it clear that the value is in base 16.
The HEX command is used to obtain the hexadecimal equivalent of a decimal number. HEX + - decval. +decval -decval. For decval, specify the 1- to 8-digit decimal number that is to be converted to hexadecimal notation. The hexadecimal number is returned as a fullword.
I think some people arriving here might just be looking for:
$ ./prog `python -c 'print "\x41\x42\x43"'`
$ ./prog `perl -e 'print "\x41\x42\x43"'`
$ ./prog `ruby -e 'print "\x41\x42\x43"'`
As the type of main
indicates, arguments from the command line are strings and will require conversion to different representations.
Converting a single hexadecimal command-line argument to decimal looks like
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("%ld\n", strtol(argv[1], NULL, 16));
return 0;
}
Example usage:
$ ./hex ff
255
Using strtol
and changing the final argument from 16 to 0 as in
printf("%ld\n", strtol(argv[1], NULL, 0));
makes the program accept decimal, hexadecimal (indicated by leading 0x
, and octal (indicated by leading 0
) values:
$ ./num 0x70
112
$ ./num 070
56
$ ./num 70
70
Using the bash command shell, take advantage of ANSI-C Quoting to have the shell perform the conversion, and then your program just prints the values from the command line.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
unsigned char value = argv[i][0];
if (strlen(argv[i]) > 1)
fprintf(stderr, "%s: '%s' is longer than one byte\n", argv[0], argv[i]);
printf(i + 1 < argc ? "%u " : "%u\n", value);
}
return 0;
}
Bash supports many formats of the form $'...'
, but $'\xHH'
appears to be the closest match to your question. For example:
$ ./print-byte $'\xFF' $'\x20' $'\x32'
255 32 50
Maybe you pack the values from the command line into a string and print it.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
if (argc > 1) {
char *s = malloc(argc);
if (!s) {
fprintf(stderr, "%s: malloc: %s\n", argv[0], strerror(errno));
return 1;
}
for (i = 1; i < argc; i++)
s[i - 1] = strtol(argv[i], NULL, 16) & 0xff;
s[argc - 1] = '\0';
printf("%s\n", s);
free(s);
}
return 0;
}
In action:
$ ./pack-string 48 65 6c 6c 6f 21
Hello!
All of the above is reinventing wheels that bash and the operating system already provide for you.
$ echo $'\x48\x65\x6c\x6c\x6f\x21'
Hello!
The echo
program prints its command-line arguments on the standard output, which you can think of as a for
loop over the arguments and a printf
for each.
If you have another program that performs the decoding for you, use Command Substitution that replaces a command surrounded by backticks or $()
with its output. See examples below, which again use echo
as a placeholder.
$ echo $(perl -e 'print "\x50\x65\x72\x6c"')
Perl
$ echo `python -c 'print "\x50\x79\x74\x68\x6f\x6e"'`
Python
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With