通过它的名称查明是否存在#define

时间:2013-11-26 16:08:01

标签: c qt c-preprocessor

是否可以检查define是否存在字符串?

E.g。我有字符串“ERROR_1000”。这是一个变量,所以#ifdef似乎不起作用。是否可以检查是否使用#define定义了ERROR_1000?

PS:我现在正在使用Qt,但不要认为它有所不同,但不确定

UPD:似乎很多人都不明白这个问题。

我有很多像

这样的定义
 #define ERROR_1000 "sometext"
 #define ERROR_1001 "someothertext"

我有一个功能

 string fun(int id)
{
  //here I got this number and create string "ERROR" + id, for example "ERROR_1000"
  //so is it possible to check here, if there is a define with name ERROR_1000
  //so if define exists return string from that define
}

4 个答案:

答案 0 :(得分:1)

关于: E.g. I have string ERROR_1000. It's a variable

如果 ERROR_1000 被定义为字符串 ,预处理器#ifdef将不会将其视为 “定义”例如:

char string[]="teststring";

int main(void)
{
#ifdef teststring
    printf("%s", teststring);
#endif
    return 0;
}

printf()语句不会执行,因为#ifdef无法识别字符串。
然而 ,如果您使用#define teststring定义它...

#define teststring "teststring"

int main(void)
{
#ifdef teststring
    printf("%s", teststring);
#endif
    return 0;
}

将执行`printf()语句

注意 ,如果您有一个名为“ERROR_1000”的变量。那么你也不能有#define ERROR_1000。您必须更改其中一个以在同一代码中一起使用它们。例如:(以下将起作用)

#define ERROR_1000  "not defined"
char Error_1000[]="some other error message";

int main(void)
{
#ifdef ERROR_1000
    printf("%s", Error_1000);
#else
    printf("%s", ERROR_1000);
#endif
    return 0;
}

另请注意:在开头的C中使用的 语句,例如#ifdef或#define,都是指向环境的指令在运行之前或编译时预处理或评估  在运行时评估if()while()等语句。

关于帖子的最新修改
我认为使用#define#ifdefswitch()语句的组合,你可以做你想要的......  也许这对你有用?:

#define ERROR_1000
#define ERROR_3000
string fun(int id)
{
  buf errorMsg[80];
  sprintf(errorMsg, "ERROR_%d", id);
  switch(id){
    case 1000://this one will print
#ifdef ERROR_1000
        printf("%s", errorMsg);
#endif
        break;
    case 2000://this one will NOT print
#ifdef ERROR_2000
        printf("%s", errorMsg);
#endif


        break;
    case 3000://this one will print
#ifdef ERROR_3000
        printf("%s", errorMsg);
#endif
        break;
  }



  //here I got this number and create string "ERROR" + id, for example "ERROR_1000"
  //so is it possible to check here, if there is a define with name ERROR_1000
  //so if define exists return string from that define
}  
使用switch()

选项不 (修改您的函数以使用#defines)
也许这方面的一些变化可行......?

#define ERROR_1000 "ERROR_1000"  //will print
#define ERROR_2000 ""  //will not print
#define ERROR_3000 "ERROR_3000"  //will print

void fun(int id, char *print);

int main(void)
{
      fun(1000, ERROR_1000);
      return 0;
}

void fun(int id, char *print)
{
      char errorMsg[80];

     if(strlen(print)>0)
     {
           sprintf(errorMsg, "ERROR_%d is %s", id, print);
           printf("%s", errorMsg);
     }
}

答案 1 :(得分:0)

试试这个:

#ifdef ERROR_1000
printf("ERROR_1000 defined");
#else
printf("ERROR_1000 not defined");
#endif

参考您的更新:

  

是否可以在此检查,如果存在名称为ERROR_1000

的定义

没有

在运行期间检查某些#define是否存在是不可能的,因为这样就不行了。甚至在编译时也是不可能的,因为预处理器每次在thr源中使用它们时,它们也已经被重新放置了。


可能的方法:

typedef enum errors_e
{
  no_error = 0
  error_1 = 1,
  error_oom = 1,
  error_2 = 2,
  error_disk = 2, 
  ...
  error_9999 = 9999;
  error_unknown = 9999,
} error_code_t;

typedef struct error_message_s
{
  const error_code_t ec;
  const char * et;
} error_message_t

#define ERROR_0001 "out of memory"
#define ERROR_0002 "general failure reading hard disk"
...
#define ERROR_9999 "unkown error"

const error_message_t error_messages[] = {
  { error_1, ERROR_0001 },
  { error_2, ERROR_0002 },
  ...
  { error_9999, ERROR_9999 },
};

const char * fun(error_code_t id)
{
  size index_to_error_messages_array;

  /* Add some clever logic to finds the index to the element 
     in error_messages where ec equals id here .*/

  return error_messages[index_to_error_messages_array]; 
}

答案 2 :(得分:0)

就像它的名字所说的那样,预处理器#ifdef将检查编译时间,如果你想在运行时做出决定,你需要使用正常的if语句。

如果ERROR_1000是参数,则正确的方法应为:

int main(int argc, char* argv){
   if(argc>1){
      if(argc[1]=="ERROR_1000"){
        // some action
      }
   }
}

答案 3 :(得分:0)

因此,您有一个包含字符串“ERROR_1000”的变量,并且您想确定相应的ERROR_1000宏是否为#define d。

不幸的是,没有好的方法可以在运行时在C中做出这个决定。在预处理之后,宏不再存在;编译后的代码中没有定义ERROR_1000。相反,在编译代码之前,ERROR_1000的每个实例都替换为字符串"sometext"

以下是非常丑陋的解决方法,但它应该有效:构建一个查找表,其中宏名称是键,但只有在定义宏时才包含它:

#define ERROR_1000 "sometext"
#define ERROR_1001 "some other text"
...
#define SEP
struct {
  char *errcode;
  char *errtext;
} code_lookup_table[] = {

#if defined( ERROR_1000 )
  SEP  { "ERROR_1000", ERROR_1000 } 
#define SEP ,
#endif

#if defined ( ERROR_1001 )
  SEP { "ERROR_1001", ERROR_1001 } 
#define SEP ,
#endif
...
};

如果同时定义了ERROR_1000ERROR_1001,则预处理的代码将类似于

struct {
  char *errcode;
  char *errtext;
} code_lookup_table[] = {

  { "ERROR_1000", "sometext" }

, { "ERROR_1001", "some other text" }

  ...
};

但是,我建议你重新考虑这个用例;这有点像你设计中的问题。