Программный способ получить имя переменной в C?

, Как Вы получаете список всех установленных шрифтов?

var fontsCollection = new InstalledFontCollection();
foreach (var fontFamiliy in fontsCollection.Families)
{
    if (fontFamiliy.Name == fontName) ... \\ installed
}

См. класс InstalledFontCollection для деталей.

MSDN:
Установленные шрифты Перечисления

31
задан unwind 26 October 2009 в 07:32
поделиться

6 ответов

Вы можете попробовать что-то вроде этого:

#define DUMP(varname) fprintf(stderr, "%s = %x", #varname, varname);

Я использовал этот заголовок Я писал, когда я был новичком в C, он может содержать некоторые полезные идеи. Например, это позволит вам распечатать значение C и предоставить спецификатор формата в одном (а также некоторую дополнительную информацию):

#define TRACE(fmt, var) \
        (error_at_line(0, 0, __FILE__, __LINE__, "%s : " fmt, #var, var))

Если вы используете C ++, вы можете использовать тип переданного значения и вывести его соответствующим образом . Я могу предоставить гораздо более прибыльный пример того, как «красиво печатать» значения переменных, если это так.

51
ответ дан 27 November 2019 в 21:41
поделиться

Если вам нужно сделать это для произвольных переменных, вам, вероятно, потребуется использовать API-интерфейс отладчика, предоставляемый компилятором или платформой (например, DbgHelp в Windows).

В некоторых встроенных системах Я работал над тем, чтобы у нас была возможность отображать по команде значения некоторых важных переменных, которые известны заранее, и для этого все, что нам нужно, это простая таблица имени / указателя:

typedef 
struct vartab {
    char const* name;
    int * var;
} vartab;


vartab varTable[] = {
    { "foo", &foo },
    { "bar", &bar }
};

Затем я просто использовал небольшая процедура, которая ищет в таблице имя переменной, о которой идет речь, и выводит имя и данные, на которые указывает указатель. Если вам нужно выгрузить данные, отличные от обычных int, вы можете расширить структуру, чтобы она также содержала форматировщик в стиле printf, и измените указатель на void * и передать этот мусор в snprintf () или что-то в этом роде для форматирования данных.

Иногда я ' Я также буду использовать макрос, который помогает построить таблицу (возможно, также объявив переменную). Но, честно говоря, я думаю, что это действительно только усложняет понимание (особенно для тех, кто недавно присоединился к проекту - у них часто бывает небольшой момент «Что за фигня?») И на самом деле не очень упрощает.

4
ответ дан 27 November 2019 в 21:41
поделиться

На самом деле у меня есть код, который может делать то, что вы хотите. Он использует препроцессор для преобразования имени переменной в строку, чтобы вы могли его распечатать. Он выводит как имя и значение переменной (в зависимости от типа), так и структуру памяти для этой переменной. Следующая программа показывает, как это делается:

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

static void dumpMem (unsigned char *p, unsigned int s) {
    int i;
    unsigned char c[0x10];
    printf (">>      ");
    for (i = 0; i < 0x10; i++) printf (" +%x",i);
    printf (" +");
    for (i = 0; i < 0x10; i++) printf ("%x",i);
    printf ("\n");
    for (i = 0; i < ((s + 15) & 0xfff0); i++) {
        if ((i % 0x10) == 0) {
            if (i != 0) printf ("  %*.*s\n", 0x10, 0x10, c);
            printf (">> %04x ",i);
        }
        if (i < s) {
            printf (" %02x", p[i]);
            c[i & 0xf] = ((p[i] < 0x20) || (p[i] > 0x7e)) ? '.' : p[i];
        } else {
            printf ("   ");
            c[i & 0xf] = ' ';
        }
    }
    printf ("  %*.*s\n", 0x10, 0x10, c);
}
#define DUMPINT(x) do{printf("%s: %d\n",#x,x);dumpMem((char*)(&x),sizeof(int));}while(0)
#define DUMPSTR(x) do{printf("%s: %s\n",#x,x);dumpMem(x,strlen(x));}while(0)
#define DUMPMEM(x,s) do{printf("%s:\n",#x);dumpMem((char*)(&x),s);}while(0)

typedef struct {
    char c;
    int i;
    char c2[6];
} tStruct;

int main (void) {
    int i = 42;
    char *s = "Hello there, my name is Pax!";
    tStruct z;
    z.c = 'a'; z.i = 42; strcpy (z.c2,"Hello");

    DUMPINT (i);
    DUMPSTR (s);
    DUMPMEM (z,sizeof(z));

    return 0;
}

Это выводит:

i: 42
>>       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
>> 0000  2a 00 00 00                                      *...
s: Hello there, my name is Pax!
>>       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
>> 0000  48 65 6c 6c 6f 20 74 68 65 72 65 2c 20 6d 79 20  Hello there, my
>> 0010  6e 61 6d 65 20 69 73 20 50 61 78 21              name is Pax!
z:
>>       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
>> 0000  61 b6 16 61 2a 00 00 00 48 65 6c 6c 6f 00 0d 61  a..a*...Hello..a

И, если вам интересно, насколько корректно do {...} while (0) в макросах, то это для позволяют размещать его в любом месте кода, не беспокоясь о том, достаточно ли у вас фигурных скобок вокруг него.

6
ответ дан 27 November 2019 в 21:41
поделиться

Боюсь, что нет хорошего способа сделать это изнутри вашей программы (кроме ответа Anacrolix). Думаю, правильное решение вашей проблемы - это скрипт отладчика. В большинстве отладчиков вы даже можете подключить его для запуска каждый раз, когда отладчик прерывает выполнение программы (точка останова, вы нажимаете ^ C и т. Д.) И получаете моментальный снимок состояния вашей программы каждый раз, когда вы взаимодействуете с ней.

1
ответ дан 27 November 2019 в 21:41
поделиться

Если ваш исполняемый файл скомпилирован с отладочной информацией, вы можете получить эту информацию. Если нет, то вам, вероятно, не повезло. Итак, вы строите отладчик? Почему? Существующие отладчики для c очень зрелые. Почему бы не использовать существующие инструменты вместо того, чтобы заново изобретать колесо?

1
ответ дан 27 November 2019 в 21:41
поделиться

В C имена переменных существуют на этапе компиляции (и на этапе связывания, если переменная глобальная), но недоступны во время выполнения. Вы должны выбрать решение, которое включает буквальную строку, указывающую имя переменной.

11
ответ дан 27 November 2019 в 21:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: