2012-06-16 4 views
0

:구조체의 내용을 캐릭터 라인 화하는 매크로를 작성 내가 구조체의 내용을 확장하는 매크로를 작성하는 것을 시도하고있다

struct Str 
{ 
    int a; 
    float f; 
    char *c; 
}; 
Str s = {123, 456.789f, "AString"}; 

#define STRINGIFY_STR(x) ... // Macro to stringify x which is an instance of Str 

printf("%s", STRINGIFY_STR(s)); 

원하는 출력 : [A : 123, F : 456.789, C : AString를 ]

이렇게하는 매크로를 작성할 수 있습니까? 그렇다면, 어떻게?

+1

stringify? 매크로? 단순히 객체에 toString 메소드를 추가하지 않거나 이것을 달성하기 위해 const 참조를 취하는 free 함수를 추가하지 않는 것이 어떻습니까? 성능에 문제가 없다면'std :: ostringstream'을 사용할 수도 있습니다. – AJG85

+1

거기에 매크로가 필요한 특별한 이유가 있습니까? Str 클래스에 대해'operator <<'를 쓰는 것이 낫다. –

답변

6

매크로로 사용하려는 이유가 있습니까?

전 처리기를 사용하는 대신이 작업을 수행하는 함수를 작성해야합니다.


목표에 따라 몇 가지 옵션이 있습니다. boost formatting library은 형식이 지정된 문자열을 작성하는 데 유용한 툴킷을 제공합니다. 깨끗한 출력을 제공하기 위해 항상 overload operator<< 수 있습니다.

순수 C에서이 작업을 수행하는 경우 sprintf 패밀리 메소드가 형식화 된 출력을 생성하는 데 사용됩니다.

+0

이것은 실제로 질문에 대답하지 않습니다. –

+0

@LuchianGrigore, 그것은 약간의 코드를 사용할 수 있지만 결국에는 작동하는 출력이나 문자열과 같은 구문입니다. – chris

+1

@LuchianGrigore 옵션에 대한 유용한 정보를 추가하려고했지만 내 질문에 직접 답하는 것이 일반적으로 나쁜 습관을 홍보하는 것이라고 생각합니다. –

0

나는 접근 방식에 대해도 합니다만, 질문에 답 :

#define STRINGIFY_STR(x) \ 
    (std::string("[a: ") + std::to_string((long double)x.a) \ 
    + std::string(", f:") + std::to_string((long double)x.f) \ 
    + std::string(",c: ") + x.c + std::string("]")).c_str() 

그래도 난이 작업을 수행 멤버 함수를 작성하는 제안을.

1

이것은 매우 총체적이며 gcc/g++에서만 작동합니다.

#define STRINGIFY_STR(x) \ 
    std::string(({ std::ostringstream ss; \ 
        ss << "[a: " << x.a \ 
         << ", f: " << x.f \ 
         << ", c: " << x.c << "]"; \ 
        ss.str(); })).c_str() 

값에서 문자열을 만들어야합니다. 이런 식으로하지 마십시오. Reed의 조언을 따르십시오. 여기

내가 그것을 꽤 인쇄 할 수 있도록 당신의 struct을 수정하는 것이 방법입니다 : s을 인쇄,

struct Str 
{ 
    int a; 
    float f; 
    char *c; 

    std::ostream & dump (std::ostream &os) const { 
     return os << "[a: " << a 
        << ", f: " << f 
        << ", c: " << c << "]"; 
    } 
}; 

std::ostream & operator << (std::ostream &os, const Str &s) { 
    return s.dump(os); 
} 

Str s = {123, 456.789f, "AString"}; 

을 지금, 당신은 std::cout를 사용할 수 있습니다,

std::cout << s << std::endl; 

을 또는 경우 정말로 문자열이 필요합니다.

std::stringstream ss; 
s.dump(ss); 
puts(ss.str().c_str()); 
+0

답장을 보내 주셔서 감사합니다. 예,보기 흉하게 보입니다. 멤버 함수를 작성하는 것이 더 좋을 것입니다. – FearLeslie

0
struct stringify 
{ 
    operator std::string() const 
    { 
     return str ; 
    } 
    std::string str ; 
}; 

template < typename T > stringify operator+ (stringify s, const T& object) 
{ 
    std::ostringstream stm ; 
    stm << object ; 
    if(!s.str.empty() && !std::isspace(*s.str.rbegin())) s.str += ' ' ; 
    s.str += stm.str() ; 
    return s ; 
} 
관련 문제