문제

변수에서 데이터를 덤프하는 도구를 개발 중입니다. 변수 이름과 값도 덤프해야합니다.

내 해결책 : 변수 이름을 문자열로 저장하고 "변수 이름"을 인쇄 한 다음 그 값이 이어집니다.

변수 이름을 알 수있는 프로그래밍 방식이 있습니까?

도움이 되었습니까?

해결책

당신은 다음과 같은 것을 시도 할 수 있습니다 :

#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 ++를 사용하는 경우 전달 된 값의 유형을 사용하고 적절하게 출력 할 수 있습니다. 이 경우 가변 값을 "예쁜 인쇄"하는 방법에 대한 훨씬 유리한 예를 제공 할 수 있습니다.

다른 팁

C에서는 컴파일 단계 중에 가변 이름이 존재하지만 (변수가 글로벌 인 경우 링크 단계) 런타임에는 사용할 수 없습니다. 변수 이름을 나타내는 문자열이 포함 된 솔루션을 선택해야합니다.

나는 실제로 당신이 원하는 것을 할 수있는 코드가 있습니다. 전처리기를 사용하여 변수 이름을 문자열하여 인쇄 할 수 있습니다. 변수 이름과 값 (유형에 따라)과 해당 변수의 메모리 레이아웃을 모두 덤프합니다. 다음 프로그램은 수행 방법을 보여줍니다.

#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) 매크로에서는 주변의 버팀대가 충분한 지에 대해 걱정할 필요없이 코드의 어느 곳에도 배치 할 수 있습니다.

짧은 방법 :

#define GET_VARIABLE_NAME(Variable) (#Variable)

테스트:

#include <string>
class MyClass {};


int main(int argc, char* argv[]) {
    int foo = 0;

    std::string var_name1 = GET_VARIABLE_NAME(foo);
     char* var_name2 = GET_VARIABLE_NAME(foo);
     char* var_name3 = GET_VARIABLE_NAME(MyClass);


    return 0;
}

임의 변수에 대해이 작업을 수행 해야하는 경우 컴파일러 또는 플랫폼이 제공하는 디버거 API (Windows의 DBGHELP)를 사용해야 할 것입니다.

내가 작업 한 일부 임베디드 시스템에서 우리는 미리 알려진 특정 중요한 변수의 값을 명령에 표시 할 수 있어야했으며, 필요한 모든 것을 간단한 이름/포인터 테이블입니다.

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


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

그런 다음 문제의 변수 이름을 검색하는 작은 루틴을 사용하고 이름과 포인터가 가리키는 데이터를 덤프합니다. 일반 INT 이외의 데이터를 덤프 해야하는 경우 구조를 확장하여 Printf 스타일 형성기를 유지하고 포인터를 void* 그리고 그 쓰레기를 전달합니다 snprintf() 또는 데이터를 형식화 할 무언가.

때로는 테이블을 구축하는 데 도움이되는 매크로를 사용합니다 (아마도 변수를 선언 할 수도 있음). 그러나 솔직히 말해서, 나는 그것이 실제로 이해하는 것이 더 복잡하다고 생각합니다 (특히 프로젝트에 가입하는 새로운 사람에게는 종종 작은 "WTF"순간이 있습니까?) 실제로 많은 것을 단순화하지는 않습니다.

사람들은 종종 프로그램이 자해를 원합니다 (또는 현재 전문 용어에서 "반영"). 그러나 대부분의 프로그래밍 언어는 프로그램의 모든 세부 사항 (변수 이름, 기능 이름, 유형, 표현 구조 등)을 반영 할 수있는 적은 (예 : Java) 또는 없음 (c) 기능을 제공합니다.

이 작업을 수행하는 방법이 있습니다 모두 언어 : 단계 밖의 언어는 언어에서 해당 정보를 추출하도록 설계된 도구를 사용합니다. 이를 수행 할 수있는 도구 클래스를 프로그램 변환 시스템이라고합니다.

프로그램 변환 시스템을 사용하여 "가변 이름을 얻는"방법 및 인쇄 값에 대한 토론을 위해 답변을 참조하십시오.추적 변수를 자동으로 변경합니다

이 시도.

#define MACRO_VARIABLE_TO_STRING(Variable) ((void) Variable,#Variable)

Code (void) 변수는 void 변환입니다. 따라서 순 결과는 const char*가 컴파일러 점검에 변수 이름을 포함합니다.

이제 변수의 이름이 있고 printf ()를 사용하여 값을 인쇄 할 수 있습니다.

실행 파일이 디버깅 정보로 컴파일 된 경우이 정보를 얻을 수 있습니다. 그렇지 않다면 아마도 운이 좋지 않을 것입니다. 그래서 당신은 디버거를 만들고 있습니까? 왜요? C에 대한 기존 디버거는 매우 성숙합니다. 휠을 다시 발명하는 대신 기존 도구를 사용하지 않겠습니까?

프로그램 내부에서 그렇게 할 수있는 좋은 방법은 없습니다 (Anacrolix의 답변을 제외하고). 문제에 대한 올바른 해결책은 디버거 스크립트라고 생각합니다. 대부분의 Debuggers에서 디버거가 프로그램 실행을 방해 할 때마다 실행하기 위해 연결할 수도 있습니다 (Breakpoint, hit ^C, 등) 및 상호 작용할 때마다 프로그램 상태의 스냅 샷을 얻으십시오.

매우 정확한 대답에도 불구하고 @Matt Joiner, 나는 쓰고 싶다 전체 짧은 코드 사용 중 얼마나 간단한 지 확인하기 위해 이것을 예시합니다. #정의하다 매크로

#include <stdio.h>
#define dump(v)printf("%s",#v);
int main()
    {
    char a;
    dump(a);
    }

산출:

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top