scsi错误代码和字符串转换

时间:2014-03-13 13:32:46

标签: c linux char int

我想知道将错误代码映射到字符串的最佳方法是什么,例如在SCSI协议中,错误总是以数字形式返回。像这样:

00h GOOD
02h CHECK CONDITION
04h CONDITION MET
08h BUSY
18h RESERVATION CONFLICT
28h TASK SET FULL
30h ACA ACTIVE
40h TASK ABORTED

我想知道将这些代码动态转换为字符串副本的最佳方法是什么?我想要做一个数组或其他东西,但Ig必须制作一个长度为40h的数组,即使我不会使用大多数索引。那么最好的方法是创建一个函数,它将数字作为输入并返回一个字符串?

2 个答案:

答案 0 :(得分:0)

这是一个如何将一些代码定义为宏然后使用另一个宏函数来获取宏的字符串值的示例:

#include <stdio.h>

#define GOOD 0
#define CHECK_CONDITON 2
#define CONDITION_MET 4

/* more codes here */

#define STR_VALUE(CODE) #CODE

void print_scsi(int code) {
  char *scsi_string;

  switch (code) {
    case GOOD: 
      scsi_string = STR_VALUE(GOOD); break;
    case CHECK_CONDITON: 
      scsi_string = STR_VALUE(CHECK_CONDITON); break;
    case CONDITION_MET: 
      scsi_string = STR_VALUE(CONDITION_MET); break;

    /* ... */
  }
  printf("code: %d string: %s\n", code, scsi_string);
}

int main(void) {
  print_scsi(0);
  print_scsi(2);
  print_scsi(4);
}

运行此命令:

code: 0 string: GOOD
code: 2 string: CHECK_CONDITON
code: 4 string: CONDITION_MET

如果代码列表很长,请在单独的头文件中定义宏以及STR_VALUE,并将其包含在主程序中。

答案 1 :(得分:0)

这有点棘手,但您可以尝试使用X-macro

#include <stdio.h>

#define SCSI_ERR_TABLE                          \
    X(GOOD,            "good",            0x00) \
    X(CHECK_CONDITION, "check condition", 0x02) \
    X(CONDITION_MET,   "condition met",   0x04) \
    X(BUSY,            "busy",            0x08) \

#define X(ERR, STR, ID) ERR = ID,
enum {
    SCSI_ERR_TABLE
};
#undef X


#define X(ERR, STR, ID) {.id = ID, .string = STR},
static const struct {
    int id;
    char string[32];
} scsi_err_strings[] = { SCSI_ERR_TABLE };
#undef X

const char *scsi_get_err_string(int error)
{
    for (int i = 0; i < sizeof(scsi_err_strings) / sizeof(scsi_err_strings[0]); i++) {
        if (scsi_err_strings[i].id == error)
            return scsi_err_strings[i].string;
    }

    return NULL;
}

int main(void)
{
    int err;

    err = CHECK_CONDITION;
    printf("%d -> %s\n", err, scsi_get_err_string(err));

    err = BUSY;
    printf("%d -> %s\n", err, scsi_get_err_string(err));

    return 0;
}