數值與字串互轉是日常開發高頻需求。本文系統整理五大類轉換方案,比較優缺點、適用場景與現代最佳實踐,助你選對工具、寫出安全高效的代碼。
| 類別 | 代表函式/類別 | 優點 | 缺點 | 推薦指數 |
|---|---|---|---|---|
| CRT 庫 | itoa, atoi, sprintf, strtod | 標準 C、無相依、效能高 | 函式碎片化、無型別安全、緩衝區溢位風險 | ⭐⭐ (維護舊碼) |
| C++98 stringstream | ostringstream, istringstream | 型別安全、支援自訂型別 (運算子<</>>)、區域設定感知 | 效能較低、語法冗長、需手寫模板封裝 | ⭐⭐⭐ (標準庫純粹派) |
| Boost lexical_cast | boost::lexical_cast<Target>(Source) | 單一介面、異常安全、支援豐富型別 | 引入 Boost 重、編譯慢、內部仍用 stream | ⭐⭐⭐⭐ (已用 Boost 專案) |
| sprintf/sscanf 家族 | sprintf, snprintf, sscanf | 格式化控制最強、C/C++ 通用 | 無型別檢查、緩衝區管理易出錯、格式字串漏洞 | ⭐⭐ (特定格式化需求) |
C++17 to_chars/from_chars | std::to_chars, std::from_chars (<charconv>) | 零開銷、無例外、無區域設定、非配置記憶體、型別安全 | 不支援區域設定、浮點數支援較晚 (C++20 完善) | ⭐⭐⭐⭐⭐ 現代首選 |
<charconv>(推薦)#include <charconv>
#include <string>
#include <iostream>
int main() {
// int → string
char buf[32];
auto [ptr, ec] = std::to_chars(buf, buf+32, 42);
std::string s(buf, ptr); // "42"
// string → int
int val = 0;
std::from_chars(s.data(), s.data()+s.size(), val); // val=42, ec=errc()
// float → string (C++20 完整支援)
double d = 3.14159;
std::to_chars(buf, buf+32, d, std::chars_format::general, 6);
return 0;
}
template <typename T> std::string to_string(T val) {
std::ostringstream oss; oss << val; return oss.str();
}
template <typename T> T from_string(const std::string& s) {
std::istringstream iss(s); T val; iss >> val; return val;
}
snprintf(buf, sizeof(buf), fmt, ...)。atoi 錯誤靜默:atoi("abc") 回傳 0 無法區分「真 0」與「轉換失敗」,改用 strtol 或 from_chars。stringstream 受 std::locale 影響,跨平台解析浮點數可能失敗;from_chars 忽略區域設定,行為一致。to_chars/from_chars 或 fmt::format (C++20 std::format 前身)。「C++17 <charconv> 結束了『轉換函式百家爭鳴』的時代:它是標準化、零開銷、型別安全的終極答案。」