正如main 的类型所表明的那样,命令行中的参数是字符串,需要转换为不同的表示形式。
将单个十六进制命令行参数转换为十进制看起来像
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("%ld\n", strtol(argv[1], NULL, 16));
return 0;
}
示例用法:
$ ./hex ff
255
使用 strtol 并将最终参数从 16 更改为 0,如
printf("%ld\n", strtol(argv[1], NULL, 0));
使程序接受十进制、十六进制(前导 0x 和八进制(前导 0 表示)值:
$ ./num 0x70
112
$ ./num 070
56
$ ./num 70
70
使用 bash 命令 shell,利用 ANSI-C Quoting 让 shell 执行转换,然后您的程序只需从命令行打印值。
#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 支持$'...' 形式的多种格式,但$'\xHH' 似乎与您的问题最匹配。例如:
$ ./print-byte $'\xFF' $'\x20' $'\x32'
255 32 50
也许你将命令行中的值打包成一个字符串并打印出来。
#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;
}
在行动:
$ ./pack-string 48 65 6c 6c 6f 21
Hello!
以上所有内容都在重新发明 bash 和操作系统已经为您提供的轮子。
$ echo $'\x48\x65\x6c\x6c\x6f\x21'
Hello!
echo 程序将其命令行参数打印在标准输出上,您可以将其视为对参数的 for 循环和每个参数的 printf。
如果您有另一个程序为您执行解码,请使用Command Substitution 将反引号或$() 包围的命令替换为其输出。请参阅下面的示例,这些示例再次使用 echo 作为占位符。
$ echo $(perl -e 'print "\x50\x65\x72\x6c"')
Perl
$ echo `python -c 'print "\x50\x79\x74\x68\x6f\x6e"'`
Python