【问题标题】:displaying #define values in C在 C 中显示#define 值
【发布时间】:2012-06-06 21:56:16
【问题描述】:

我有一系列来自此类库文件头的#defines:

typedef int Lib_error;   

#define   LIB_ERROR_A      ((Lib_error) 0x0000) 
#define   LIB_ERROR_D      ((Lib_error) 0x0100)                   
#define   LIB_ERROR_F      ((Lib_error) 0x0200)                      
#define   LIB_ERROR_K      ((Lib_error) 0x0300)                
#define   LIB_ERROR_O      ((Lib_error) 0x0400)                
#define   LIB_ERROR_P      ((Lib_error) 0x0500)
#define   LIB_ERROR_R      ((Lib_error) 0x0600) 
#define   LIB_ERROR_X      ((Lib_error) 0x0700)             
#define   LIB_ERROR_Y      ((Lib_error) 0x0800) 
#define   LIB_ERROR_M      ((Lib_error) 0x0900) 
 /* and so on */

有什么办法可以分开我可以打印这些值,例如

uint MyError;
   /* printf("Error = %s",MyError); It should print the string LIB_ERROR_F instead of say 0x200 */

我可以为此使用很多 if else,但我想知道是否有更聪明的方法。请注意,无论如何我都无法更改库头文件的内容。

【问题讨论】:

    标签: c c-preprocessor


    【解决方案1】:

    人们似乎对它们有复杂的感觉,但X-macros 是一种可能的解决方案。

    但如果您不能更改标题,那么您仅有的两个选项 (AFAIK) 是:

    • 手动操作
    • 构建过程中某种形式的代码生成步骤。在您的情况下,应该可以通过使用 sed 解析头文件来实现(假设您使用的是 Linux)。

    【讨论】:

    • 我害怕那种叹息。不幸的是,更改标题是不可能的。
    • 用 cpp (cc -E) 解析,我希望!使用 sed 提取宏名称,使用 cpp 提取值,否则你会发疯(或出现细微的替换错误)。
    • 所以看完全文,我不得不问,为什么他的X宏要使用两个参数?难道他不能用#a 将名字作为文字得到吗?
    【解决方案2】:

    没有一种简单或自动的方法可以做到这一点。您必须自己生成数字和名称的列表,并提供查找函数来映射数字和名称。

    你可以看看博文'Enums, Strings and Laziness'中的想法;它有一些可能对您有所帮助的想法。 (这与 Oli Charlesworth 提到的 Dobbs 博士的 X-Macros 密切相关;那里的文章声称该技术可以追溯到 60 年代,尽管它必须是使用 C 以外的语言,因为当时 C 不存在.)

    【讨论】:

      【解决方案3】:

      警告:下面的代码片段只是一个示例。它可以即兴创作很多,这是由你来做的。 :)

      定义如下结构:

      typedef struct ErrorStorage
      {
        Lib_error err;
        char err_string[100];
      }ErrNoStore;
      
      ErrNoStore arrErr[25];
      
      arrErr[0].err = LIB_ERROR_A;
      strcpy(arrErr[0].err_string, "LIB_ERROR_A");
      /... and so on .../
      

      然后在代码中定义一个这样的函数并调用它

      void display_error(Lib_error errnum)
      {
        int i = 0;
      
        for(i=0; i<25;i++)
        {
          if(errnum == arrErr[i].err)
          {
             printf("%s\n", arrErr[i].err_string);
          }
        }
      }
      

      }

      【讨论】:

      • 我只需要这样做
      【解决方案4】:

      只需通过用某种脚本语言解析这些定义来生成一个表。应该很容易将这些定义转换为常量代码数组的声明,然后可以迭代的字符串结构。
      假设库不经常更改,您只需要这样做一次,因此您无需为脚本的正确性等操心。

      【讨论】:

        猜你喜欢
        • 2010-12-06
        • 2012-03-30
        • 1970-01-01
        • 2011-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多