一、场景和炼狱
我想,你肯定也遇到过这样的场景,传入的多个参数要通过字符串拼接成一条指令,各种数据类型(我们先只说基本数据类型),然后一通转换,一通拼接。如果处理的多了,这也将是一场人间炼狱。
打个比方。我有这样的一个指令,如下:
/***************************************************** SPUL HighSetpoint,LowSetpoint,Frequency,DutyCycle* int int int float* SPUL 150, 10, 100, 0.75*****************************************************/
二、磨刀霍霍
我编写了一个如下的接口用于生成和发送指令
virtual _Check_return_ I64 set_software_plusing( _In_ int HighSetpoint,_In_ int LowSetpoint,_In_ int Frequency,_In_ float DutyCycle)
{// std::string cmd = "SPUL " + std::to_string(HighSetpoint) + "," ... return sendCommand(cmd,ERR_SPUL,"set software plusing error.");
}
写了一个我就拼不下去了,这TM的要命啊。有没有什么快速的std::string 字符串格式化生成的办法呢?
答案是肯定的。有一个不错的开源项目 fmt
, 你可以在 https://github.com/fmtlib/fmt 找到 fmt 库的源代码和安装说明。
但是,我显然不可能为了用个手枪,然后把武器库拿过来吧,不用fmt的原罪是我嫌弃他“臃肿”;
没办法,手撸一个。
三、临阵"造"枪
#include <iostream>
#include <utility>
#include <sstream>
#include <string>namespace myfmt {
template<typename... Args>
std::string format(const std::string& fmt, Args... args)
{std::stringstream ss;formatHelper(ss, fmt, args...);return ss.str();
}template<typename T, typename... Args>
void formatHelper(std::ostream& os, const std::string& fmt, T value, Args... args)
{size_t pos = fmt.find("{}");if(pos != std::string::npos){os << fmt.substr(0, pos);os << value;formatHelper(os, fmt.substr(pos + 2), args...);}else{os << fmt;}
}
void formatHelper(std::ostream& os, const std::string& fmt)
{os << fmt;
}}//end of namespace myfmtint main() {std::string s = myfmt::format("dooooo {},{},{}", 42, 3.36, "this is a girl");std::cout << s << std::endl;}
当然,还有一些不完美的地方,不够黑大粗,不过笔者项目已经够用,那又有什么问题,暂不做优化和更多的拓展了。