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

Write a Macro to stringify the contents of a struct

本文关键字:结构 字符串      更新时间:2023-10-16

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

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, 传真:456.789, c:AString]

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

有什么理由想把它作为一个宏来做吗?

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


根据您的目标,有几种选择。 提升格式库提供了一个很好的工具包来构建格式化字符串。 您也可以始终重载operator<<以提供干净的输出。

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

这很恶心,仅适用于 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());
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 ;
}

我也反对这种方法,但要回答这个问题:

#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()

我建议编写一个成员函数来执行此操作。