0

次のようなフラグ定義があると想定します。

SHF_WRITE     0x1
SHF_ALLOC     0x2
SHF_EXECINSTR 0x4
SHF_MASKPROC  0xf0000000

フラグが与えられたSHF_WRITE|SHF_ALLOC場合、ビット0x10x2がオンの場合に出力する必要があります。

Cでトリックを行う方法は?

4

3 に答える 3

5
#define V(n) { n, #n }

struct Code {
  int  value;
  char *name;
} decode[] = {
  V(SHF_WRITE),
  V(SHF_ALLOC),
  { 0, NULL },
};

void f(const int x) {
  struct Code *c = decode;
  int beenthere = 0;

  for(; c->name; ++c)
    if(x & c->value)
      printf("%s%s", beenthere++ ? "|" : "", c->name);
  if(beenthere)
    printf("\n");
}
于 2011-07-03T04:25:16.890 に答える
3

文字列の可能なすべての組み合わせを保持するのに十分なスペースのある文字バッファを作成し、該当するビットセットごとに適切な文字列を追加するだけです。(または、バッファを捨ててstdoutに直接書き込むこともできますが、これを選択してください)このようなことを行う方法の素朴な実装を次に示します。

void print_flags(int flag)
{
#define BUFLEN (9+9+13+12+3+1)
                  /* for the text, pipes and null terminator*/
#define PAIRLEN 4
static struct { int value; const char *string; } pair[] =
{
    { SHF_WRITE,     "SHF_WRITE" },
    { SHF_ALLOC,     "SHF_ALLOC" },
    { SHF_EXECINSTR, "SHF_EXECINSTR" },
    { SHF_MASKPROC,  "SHF_MASKPROC" },
};

    char buf[BUFLEN];  /* declare the buffer */
    char *write = buf;    /* and a "write" pointer */
    int i;
    for (i = 0; i < PAIRLEN; i++)
    {
        if ((flag & pair[i].value) == pair[i].value) /* if flag is set... */
        {
            size_t written = write - buf;
            write += _snprintf(write, BUFLEN-written, "%s%s",
                written > 0 ? "|" : "",
                pair[i].string); /* write to the buffer */
        }
    }
    if (write != buf) /* if any of the flags were set... */
    {
        *write = '\0'; /* null terminate (just in case) */
        printf("(%s)", buf); /* print out the buffer */
    }
#undef PAIRLEN
#undef BUFLEN
}
于 2011-07-03T04:02:45.283 に答える
0

問題:

「SHF_WRITE|SHF_ALLOC」は、「ビット0x1および02x」ではなく、「ビット0x1またはビット0x2」を示します。

それでも、ビット0x1と0x2の両方が値「フラグ」で「オン」になっている場合に「SOMEMSG」を出力したい場合は、次のようにします。

  if (flag & SHF_WRITE & SHF_ALLOC)
    printf ("SOME MSG, flag= 0x%x\n", flag);

値が「オン」になっているビットのテキスト表現を出力する場合は、次のようにします。

  char buf[80] = '\0';
  if (flag & SHF_WRITE)
    strcpy (buf, " SHF_WRITE");
  if (flag & SHF_ALLOC)
    strcpy (buf, " SHF_ALLOC");
  ...
  printf ("SOME MSG, flag= %s\n", buf);

そして最後に、ビットが設定されていない場合に印刷したくない場合は、次のようにします。

  if (flag)
  {
    ... do printing ...
  }
  else
  {
    ... do nothing? ...
  }

于 2011-07-03T04:10:42.617 に答える