编写宏来字符串化结构的内容

时间:2012-06-16 00:54:04

标签: c++ struct stringify

我正在尝试编写一个宏来扩展结构的内容:

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]

是否可以编写一个执行此操作的宏?如果是,那怎么样?

4 个答案:

答案 0 :(得分:6)

您是否有理由将此作为宏?

您应编写一个函数来执行此操作,而不是使用预处理器。


根据您的目标,有一些选择。 boost formatting library提供了一个很好的工具包来构建格式化的字符串。你总是可以overload operator<<提供干净的输出。

如果您在纯C中执行此操作,sprintf系列方法可用于创建格式化输出。

答案 1 :(得分: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());

答案 2 :(得分:1)

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

答案 3 :(得分: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()

我建议写一个成员函数来做到这一点。