2012-06-16 26 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)); 

期望的輸出:[α:123,F:456.789,C:ASTRING ]

是否可以編寫一個這樣做的宏?如果是,那麼如何?

+1

stringify?宏?爲什麼不簡單地添加一個'toString'方法到你的對象或一個自由函數,它需要一個const引用來實現呢?如果性能不是問題,你甚至可以使用'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() 

您必須從值中創建字符串。請不要這樣做。請按照裏德的建議。

這是我會怎麼修改struct允許它要美化打印:

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"}; 

現在,打印出來s,您可以使用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 ; 
} 
相關問題