Получение шестнадцатеричного числа в программу через командную строку

Я могу сделать это:

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

Но что правильный путь состоит в том, чтобы получить шестнадцатеричное число в программу через командную строку?

unsigned char cTest = argv[1];

не добивается цели. Это производит инициализацию, делает целое число из указателя без предупреждения броска.

9
задан Ruben Bartelink 29 January 2010 в 15:32
поделиться

5 ответов

Как указывает тип 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, воспользуйтесь преимуществами ANSI-C Quiting , чтобы оболочка выполняла преобразование, а затем ваша программа просто печатает значения из командной строки.

#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 для каждого.

Если у вас есть другая программа, которая выполняет декодирование за вас, используйте Подстановку команд , которая заменяет команду, заключенную в обратные кавычки, или $ () своим выводом. См. Примеры ниже, где снова используется echo в качестве заполнителя.

$ echo $(perl -e 'print "\x50\x65\x72\x6c"')
Perl
$ echo `python -c 'print "\x50\x79\x74\x68\x6f\x6e"'`
Python
8
ответ дан 4 December 2019 в 07:14
поделиться

Вы могли бы использовать Strtoul , который будет проходить через символы в строке и преобразует их, с учетом Radix (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 , и у вас есть только Unsive Char Это в?

, например, с SSCANF :

int val;
sscanf(argv[1], &val)
printf("%d\n", val); 
7
ответ дан 4 December 2019 в 07:14
поделиться

Традиционный способ сделать этот вид вещей в C - это с Scanf () . Это именно обратный отпечаток печати (), чтение данного формата из файла (или терминала) и в список переменных, а не написать их в него.

В вашем случае вы используете SSCANF , так как вы уже получили его в строке, а не по потоку.

1
ответ дан 4 December 2019 в 07:14
поделиться
unsigned char cTest = argv[1];

неправильно, потому что argv[1] имеет тип char *. Если argv[1] содержит нечто подобное "0xff" и вы хотите присвоить целое значение, соответствующее этому, неподписанному символу char -, самым простым способом, вероятно, было бы использовать strtoul(), чтобы сначала преобразовать его в беззнаковый длинный, а затем проверить, является ли преобразованное значение меньше или равно UCHAR_MAX. Если да, то можно просто присвоить cTest. Третий параметр

strtoul() является базовым, который может быть равен 0 для обозначения разбора числа в стиле C (разрешены восьмеричные и шестнадцатеричные литералы). Если вы хотите разрешить только базу 16, передайте ее в качестве третьего аргумента в strtoul(). Если вы хотите разрешить любую базу (чтобы можно было разобрать 0xff, 0377, 255 и т.д.), используйте 0.

UCHAR_MAX определено в <лимиты.h>.

4
ответ дан 4 December 2019 в 07:14
поделиться

ATOI , ATOL , Строй , СТРОЛ

Все в stdlib.h

-3
ответ дан 4 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: