C/C++使用fmt库实现格式化字符串
作者:liulilittle
fmt库是一个高效、易用的C++格式化库,可以帮助我们方便地进行字符串格式化、输出、日志记录等操作,下面我们就来学习一下fmt格式化字符串的具体操作吧
实现的目的;提高 C/C++ 编译速度,fmt 库模板嵌套过多编译速度非常慢,且编译后程序体积也过大,函数步入的栈帧过多!
只支持格式;{}
不支持格式;{:02x}
class fmt { public: template <typename S, typename ...T> static std::string format(const S& fmt, T ... args) noexcept { std::string str; if constexpr (std::is_same<S, std::string>::value) { str = fmt; } else if constexpr (std::is_same<S, std::string_view>::value) { str = std::string(fmt.data(), fmt.size()); } else { str = fmt; } (..., format_string(str, args)); return str; } template <typename OutputIt, typename ...T> static void format_to(OutputIt&& out, const std::string& fmt, T ... args) { std::string result = format(fmt, std::forward<T&&>(args)...); for (char ch : result) { *out = ch; } } private: template <typename T> static std::string to_string(const T& value) noexcept { if constexpr (std::is_same<T, bool>::value) { return value ? "true" : "false"; } else if constexpr (std::is_pointer<T>::value) { using DECAY_T = typename std::decay<T>::type; if constexpr (std::is_same<char*, DECAY_T>::value || std::is_same<const char*, DECAY_T>::value) { return value ? value : ""; } else { if (value) { char buf[sizeof(value) << 2]; snprintf(buf, sizeof(buf), "%p", reinterpret_cast<const void*>(value)); return buf; } return "null"; } } else if constexpr (std::is_same<T, std::string>::value) { return value; } else if constexpr (std::is_same<T, std::string_view>::value) { return std::string(value.data(), value.size()); } else { return std::to_string(value); } } template <typename T> static std::string to_string(const std::shared_ptr<T>& value) noexcept { return fmt::to_string(value.get()); } template <typename T> static void format_string(std::string& out, const T& value) noexcept { replace_string(out, "{}"sv, fmt::to_string(value)); } public: static bool replace_string(std::string& str, const std::string_view& old_string, const std::string_view& new_string) noexcept; }; inline bool fmt::replace_string(std::string& str, const std::string_view& old_string, const std::string_view& new_string) noexcept { size_t pos = str.find(old_string); if (pos == std::string::npos) { return false; } str.replace(pos, old_string.length(), new_string); return true; }
方法补充
除了上文的方法,小编还为大家整理了其他C++格式化字符串的方法,希望对大家有所帮助
1.使用C++中的字符串流(stringstream)
例如:
#include <sstream> std::stringstream ss; int num = 42; const char* str = "hello"; ss << "Num: " << num << ", str: " << str; std::string result = ss.str();
上述代码中,我们使用字符串流将数字和字符串插入到字符串中,得到了最终的格式化结果。
需要注意的是,当处理浮点数时,可能会出现精度误差的问题,可以使用std::setprecision
函数来指定小数点后的位数。
示例说明
下面是一个例子,展示了使用字符串流格式化浮点数的方法:
#include <sstream> #include <iomanip> std::stringstream ss; double num = 3.14159265358979323846; ss << "The value of pi is approximately " << std::setprecision(6) << std::fixed << num; std::string result = ss.str();
上述代码中,我们使用字符串流将浮点数插入到字符串中,并设置小数点后6位的精度,输出结果为:
The value of pi is approximately 3.141593.
2.使用format库
format库是C++11格式化字符串的一种解决方案,它的设计目标是提供简单、便捷的格式化语法,并且不需要调用大量的函数来实现字符串的格式化。
format库可以被看作是一个功能强大的printf的替代品。在使用上它更加灵活,更加安全,而且能够提供更加友好的错误提示。
format库的使用方式和Python的字符串格式化方式非常相似,适合需要频繁使用字符串格式化的场景。
具体用法
#include <fmt/format.h> #include <iostream> int main(){ std::cout << fmt::format("{} {} {}!\n", "Hello", "World", 123); std::cout << fmt::format("{2} {1} {0}!\n", "Hello", "World", 123); std::cout << fmt::format("{0:+} {0:-} {0:#}\n", 123); std::cout << fmt::format("{0:.3f} {0:7.3f}\n", 3.1415926535); std::cout << fmt::format("{{ }}\n"); return 0; }
到此这篇关于C/C++使用fmt库实现格式化字符串的文章就介绍到这了,更多相关C++格式化字符串内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!