Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 通过命令行将十六进制数输入程序_C_Base Conversion_Strtol - Fatal编程技术网

C 通过命令行将十六进制数输入程序

C 通过命令行将十六进制数输入程序,c,base-conversion,strtol,C,Base Conversion,Strtol,我可以这样做: int main(int argc, char** argv) { unsigned char cTest = 0xff; return 0; } 但是,通过命令行将十六进制数输入程序的正确方法是什么 unsigned char cTest=argv[1] 这没用。它从指针生成一个初始化整数,不带强制转换警告。您可以使用它遍历字符串中的字符并转换它们,同时考虑传入的基数(在本上下文中为16):- char *terminatedAt; if (argc != 2)

我可以这样做:

int main(int argc, char** argv) {
  unsigned char cTest = 0xff;
  return 0;
}
但是,通过命令行将十六进制数输入程序的正确方法是什么

unsigned char cTest=argv[1]

这没用。它从指针生成一个初始化整数,不带强制转换警告。

您可以使用它遍历字符串中的字符并转换它们,同时考虑传入的基数(在本上下文中为16):-

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);
如其他示例所述,有一些较短的方法,但它们都不允许您对处理进行彻底的错误检查(如果有人通过
FFF
,而您只有一个
unsiged char
来放入,会发生什么情况

e、 g.使用
sscanf

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

正如
main
的类型所示,来自命令行的参数是字符串,需要转换为不同的表示形式

将单个十六进制命令行参数转换为十进制

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

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

  return 0;
}
使用
strtol
并将最终参数从16更改为0,如中所示

printf("%ld\n", strtol(argv[1], NULL, 0));
使程序接受十进制、十六进制(由前导
0x
表示)和八进制(由前导
0
表示)值:

使用bash命令shell,利用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;
}
也许可以将命令行中的值打包成字符串并打印出来

#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;
}
所有这些都是对bash和操作系统已经为您提供的轮子的重新发明

$ echo $'\x48\x65\x6c\x6c\x6f\x21'
Hello!
echo
程序在标准输出上打印其命令行参数,您可以将其视为参数上的
for
循环和每个参数的
printf

如果您有另一个程序为您执行解码,请使用其输出替换由反勾号或
$()
包围的命令。请参阅下面的示例,其中再次使用
echo
作为占位符

$ echo $(perl -e 'print "\x50\x65\x72\x6c"')
Perl
$ echo `python -c 'print "\x50\x79\x74\x68\x6f\x6e"'`
Python

atoi
atol
strtoi
strtol

全功能
stdlib.h

unsigned char cTest = argv[1];
是错误的,因为
argv[1]
属于
char*
类型。如果
argv[1]
包含类似
“0xff”
的内容,并且您希望将与之对应的整数值分配给
无符号char
,最简单的方法可能是使用
strtoul()
首先将其转换为
无符号长型
,然后检查转换后的值是否小于或等于
UCHAR_MAX
。如果是,您可以只分配给
cTest

strtoul()
的第三个参数是一个base,可以是0来表示C风格的数字解析(允许使用八进制和十六进制文字)。如果只允许base 16,则将其作为第三个参数传递给
strtoul()
。如果要允许任何base(因此您可以解析
0xff
0377
255
,等等),使用0


UCHAR\u MAX
是在

中定义的。在C中进行此类操作的传统方法是使用。它与printf()完全相反,从文件(或终端)中读取给定格式并将其写入所列变量,而不是将它们写入其中


在您的情况下,您应该使用
sscanf
,因为您已经将其放入字符串而不是流中。

我认为一些来到这里的人可能只是在寻找:

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

命令行参数始终是字符串。某些平台可能将其设置为Unicode,在这种情况下,简单的
strtol
将不起作用。@直接:在这种情况下,
mbstol
或任何多字节或宽字符(或TCHAR)变体将涵盖这一点?(我也怀疑这是一个关键问题,因为question@dirkgently:在这种情况下,是
main()的第二个参数
不是类型
char**
?这不符合标准。@Alok:它们可能仍然是多字节的,在这种情况下,mbstoul最好,但在问题的上下文中,这太花哨了。我认为+1很好的解释,考虑到我在代码中试图展示的大多数观点背后的推理都在3分钟前指出(另请参见链接的手册页)但这并不能帮助提问者理解为什么有必要这样做或给出一个示例。当帖子没有添加时,最好将其删除以保持干燥
UCHAR\u MAX
可能大于
LONG\u MAX
,因此您应该使用
strtoul()和 Value> 255 > <代码>应该是“代码>值> UCHAROXMAX 。最后, StistalyCase是C++,这里不需要强制转换因为隐式转换规则。Ta,我在初版中有一个<代码> CUT//CUT>:P我考虑使用U,但是考虑到这个问题会使问题变得过于复杂。oner主要是想理解一个对他们来说不太明显的概念。我同意有时一个人必须让事情对初学者来说不完全是学究式的正确,但在这种情况下,我认为学究式的学习对初学者来说也不难。这将阻止许多人假设
UCHAR\u MAX==255
LONG\u MAX>UCHAR_MAX
,等等。谢谢你的编辑和一个好的答案!@Alok:总是很高兴学究,谢谢!我认为演员阵容很好,因为它解释了读者发生了什么,并且避免了关于缩短转换的警告。我将忽略mbs问题(以及wchar_t问题,因为问题排除了它们).一遍又一遍!我是。非常感谢!非常感谢-非常非常有帮助
$ echo $'\x48\x65\x6c\x6c\x6f\x21'
Hello!
$ echo $(perl -e 'print "\x50\x65\x72\x6c"')
Perl
$ echo `python -c 'print "\x50\x79\x74\x68\x6f\x6e"'`
Python
unsigned char cTest = argv[1];
$ ./prog `python -c 'print "\x41\x42\x43"'`
$ ./prog `perl -e 'print "\x41\x42\x43"'`
$ ./prog `ruby -e 'print "\x41\x42\x43"'`