Автоматическая замена переменных с помощью #defines - PullRequest
3 голосов
/ 08 февраля 2009

У меня есть файл с примерно 100 #defines в нем, от 1 до 100, и каждый с уникальным строковым значением.

Теперь я пытаюсь напечатать это значение, но вместо значения я хочу напечатать, что такое #define. Например:

#define FIRST_VALUE 1
var = FIRST_VALUE;
printf("%s", var);

и я хочу, чтобы printf печатал FIRST_VALUE, а не 1.

Есть ли способ сделать это в C? Или я должен просто выписать более 100 блоков внутри оператора switch?

Ответы [ 3 ]

12 голосов
/ 08 февраля 2009

Вы можете использовать stringification для достижения того, что вы ищете:

  #define FIRST_MACRO
  #define MACRO_TO_STRING(x) #x

  #include <stdio.h>

  main() {
     printf("%s\n",  MACRO_TO_STRING(FIRST_MACRO));
  }

Эта программа выведет:

FIRST_MACRO
1 голос
/ 09 февраля 2009

Поговорив с одним из моих ТА в школе, мы решили, что лучший способ сделать это - написать скрипт AWK для обработки файла заголовка и автоматически сгенерировать все необходимые операторы case.

Спасибо, ребята!

0 голосов
/ 02 марта 2009

Вы не можете делать именно то, что вам нужно, поскольку к тому времени, когда компилятор получает выходные данные препроцессора, токен "ONE" уже давно исчез. Однако, если ваша цель состоит в том, чтобы написать список констант один раз, но сгенерировать как токены, так и строки, то это можно сделать.

Сначала используйте макрос для построения констант в виде перечислений в заголовочном файле. Файл enums.h:

#ifndef ENUMS_H
#define ENUMS_H

#ifndef ENUM
#define ENUM(name,val) enum { name = val };
#endif

ENUM(ONE,1)
ENUM(TWO,2)
ENUM(THREE,3)

#endif /* ENUMS_H */

Во-вторых, переопределите макрос в файле .c, чтобы создать строковое / целочисленное отображение, и включите файл .h в нужное место. Файл enums.c:

#include 
#include 

typedef struct {
        char *str;
        int val;
} DescriptiveEnum;

static DescriptiveEnum enums[] = {
#define ENUM(name,val) { #name, val },
#include "enums.h"
};
#define NUM_ENUMS (sizeof(enums)/sizeof(enums[0]))

char *enum_to_str(int val)
{
        int i;
        for (i=0;i<NUM_ENUMS;i++) {
                if (enums[i].val == val) return enums[i].str;
        }
        return "";
}

Теперь и константы перечисления, и функция отображения доступны для вызывающих. Файл main.c:

#include <stdio.h>
#include <stdlib.h>
#include "enums.h"

char *enum_to_str(int val);

int main(int argc, char *argv[])
{
        int val;

        val = ONE;

        printf("%d %s\n",val,enum_to_str(val));

        return EXIT_SUCCESS;
}
...