C/C++使用fmt庫(kù)實(shí)現(xiàn)格式化字符串
實(shí)現(xiàn)的目的;提高 C/C++ 編譯速度,fmt 庫(kù)模板嵌套過多編譯速度非常慢,且編譯后程序體積也過大,函數(shù)步入的棧幀過多!
只支持格式;{}
不支持格式;{: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;
}方法補(bǔ)充
除了上文的方法,小編還為大家整理了其他C++格式化字符串的方法,希望對(duì)大家有所幫助
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();
上述代碼中,我們使用字符串流將數(shù)字和字符串插入到字符串中,得到了最終的格式化結(jié)果。
需要注意的是,當(dāng)處理浮點(diǎn)數(shù)時(shí),可能會(huì)出現(xiàn)精度誤差的問題,可以使用std::setprecision函數(shù)來指定小數(shù)點(diǎn)后的位數(shù)。
示例說明
下面是一個(gè)例子,展示了使用字符串流格式化浮點(diǎn)數(shù)的方法:
#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();
上述代碼中,我們使用字符串流將浮點(diǎn)數(shù)插入到字符串中,并設(shè)置小數(shù)點(diǎn)后6位的精度,輸出結(jié)果為:
The value of pi is approximately 3.141593.
2.使用format庫(kù)
format庫(kù)是C++11格式化字符串的一種解決方案,它的設(shè)計(jì)目標(biāo)是提供簡(jiǎn)單、便捷的格式化語(yǔ)法,并且不需要調(diào)用大量的函數(shù)來實(shí)現(xiàn)字符串的格式化。
format庫(kù)可以被看作是一個(gè)功能強(qiáng)大的printf的替代品。在使用上它更加靈活,更加安全,而且能夠提供更加友好的錯(cuò)誤提示。
format庫(kù)的使用方式和Python的字符串格式化方式非常相似,適合需要頻繁使用字符串格式化的場(chǎng)景。
具體用法
#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;
}到此這篇關(guān)于C/C++使用fmt庫(kù)實(shí)現(xiàn)格式化字符串的文章就介紹到這了,更多相關(guān)C++格式化字符串內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言驅(qū)動(dòng)開發(fā)之內(nèi)核通過PEB獲取進(jìn)程參數(shù)
PEB結(jié)構(gòu)(Process Envirorment Block Structure)其中文名是進(jìn)程環(huán)境塊信息。本文將通過PEB實(shí)現(xiàn)獲取進(jìn)程參數(shù),感興趣的小伙伴可以了解一下2022-10-10
基于Qt播放器的實(shí)現(xiàn)詳解(支持Rgb,YUV格式)
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)簡(jiǎn)易的播放器,可以支持支持Rgb,YUV格式。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-12-12
C語(yǔ)言連續(xù)生成隨機(jī)數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了C語(yǔ)言連續(xù)生成隨機(jī)數(shù)的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易掃雷游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
OpenCV實(shí)現(xiàn)圖像的直線檢測(cè)
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像直線檢測(cè)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
C++實(shí)現(xiàn)LeetCode(87.攪亂字符串)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(87.攪亂字符串),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C/C++?Qt?Tree與Tab組件實(shí)現(xiàn)分頁(yè)菜單功能
這篇文章主要介紹了C/C++?Qt?Tree與Tab組件實(shí)現(xiàn)分頁(yè)菜單功能,實(shí)現(xiàn)一個(gè)類似于樹形菜單欄的功能,當(dāng)用戶點(diǎn)擊菜單欄中的選項(xiàng)時(shí)則會(huì)跳轉(zhuǎn)到不同的頁(yè)面上,本文簡(jiǎn)單給大家分享實(shí)現(xiàn)代碼,感興趣的朋友跟隨小編一起看看吧2021-11-11

