13

私がすることができます:

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

しかし、コマンドラインを介してプログラムに16進数を取り込む正しい方法は何ですか?

unsigned char cTest = argv[1];

トリックをしません。これにより、キャスト警告なしでポインタから整数になる初期化が生成されます。

4

6 に答える 6

17

ここに到着した人の中には、次のものを探している人もいると思います。

$ ./prog `python -c 'print "\x41\x42\x43"'`
$ ./prog `perl -e 'print "\x41\x42\x43"'`
$ ./prog `ruby -e 'print "\x41\x42\x43"'`
于 2011-07-16T16:33:54.353 に答える
11

のタイプがmain示すように、コマンドラインからの引数は文字列であり、別の表現に変換する必要があります。

単一の16進コマンドライン引数を10進数に変換すると、次のようになります。

#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プログラムが10進数、16進数(先頭で示される) 、および8進数(先頭で示される0)の値を受け入れるようにします。

$ ./num 0x70
112
$ ./num 070
56
$ ./num 70
70

bashコマンドシェルを使用して、ANSI-C引用符を利用してシェルに変換を実行させると、プログラムはコマンドラインから値を出力するだけです。

#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
于 2010-01-29T15:20:54.453 に答える
7

渡す基数(このコンテキストでは16)を考慮して、文字列内の文字をウォークスルーして変換するstrtoulを使用できます。-

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

sscanf

int val;
sscanf(argv[1], &val)
printf("%d\n", val); 
于 2010-01-29T15:19:09.883 に答える
4
unsigned char cTest = argv[1];

argv[1]タイプがであるため、間違っていchar *ます。argv[1]のようなものが含まれて"0xff"いて、それに対応する整数値をに割り当てたい場合、unsigned char最も簡単な方法は、strtoul()最初にそれをに変換してから、unsigned long変換された値が。以下であるかどうかを確認することですUCHAR_MAX。はいの場合は、に割り当てることができますcTest

strtoul()の3番目のパラメーターはベースであり、Cスタイルの数値解析を示すために0にすることができます(8進数および16進数のリテラルを使用できます)。16進数のみを許可する場合は、それを3番目の引数として。に渡しますstrtoul()0xff任意のベースを許可する場合( 、、、など0377を解析できるようにするため255)、0を使用します。

UCHAR_MAXで定義されてい<limits.h>ます。

于 2010-01-29T15:23:12.620 に答える
1

Cでこの種のことを行う従来の方法は、scanf()を使用することです。これはprintf()の逆であり、指定された形式をファイル(またはターミナル)からリストした変数に書き込むのではなく読み取ります

あなたの場合、sscanfストリームではなく文字列ですでにそれを持っているので、あなたはそれを使うでしょう。

于 2010-01-29T15:24:49.450 に答える
-3

atoi、、、、atol_ strtoi_strtol

オールインstdlib.h

于 2010-01-29T15:21:50.110 に答える