#include <string> // std::string
#include <sstream> // std::stringstream(推薦轉換工具)
#include <cstdlib> // atoi、strtol 等 C 風格函式
// MFC/ATL 專用
#include <atlstr.h> // CString
| 來源 → 目標 | 推薦寫法 | 備註 |
|---|---|---|
int → std::string | std::to_string(n) (C++11) 或 stringstream | 最簡潔、無 locale 問題 |
std::string → int | std::stoi(s) / std::stol / std::stoll | 拋出 std::invalid_argument / out_of_range |
std::string → CString | CString(str.c_str()) 或 CString(str.c_str(), str.length()) | 構造函式直接接受 const char* |
CString → std::string | std::string(cstr.GetString()) (MFC) / std::string(CW2A(cstr)) (ATL Unicode) | 避免 GetBuffer() 配對 ReleaseBuffer() 易忘 |
char* → std::string | std::string(ptr) 或 std::string(ptr, len) | 若含 \0 中間截斷,必須指定長度 |
std::string → char* | str.c_str() (唯讀) / str.data() (C++11 保證連續) | 返回指標生命週期綁定 str,勿儲存長期使用 |
CString ↔ int | CString s; s.Format(_T("%d", n)); int n = _ttoi(s); | _ttoi 自動適配 Unicode/ANSI |
CString ↔ char* | CString s = psz; char* p = s.GetBuffer(); ... s.ReleaseBuffer(); | 修改緩衝區後必須 ReleaseBuffer |
c_str() vs data() vs copy()c_str():返回以 \0 結尾的常量指標,C++11 保證 O(1)、不拋異常。data():C++11 前不保證尾隨 \0;C++11 起等同 c_str()。copy(buf, len):將內容複製到使用者提供的緩衝區,安全可控,適合與 C API 交互。// 任意型別 → string (支援 iomanip 格式控制)
template <typename T>
std::string to_string_fmt(T value, const char* fmt = "%s") {
std::ostringstream oss;
oss << value; // 或用 snprintf 配合 fmt
return oss.str();
}
// 安全的 string → 數值(含錯誤碼)
bool try_parse_int(const std::string& s, int& out) {
try {
size_t pos;
out = std::stoi(s, &pos);
return pos == s.size(); // 整串皆為數字
} catch (...) { return false; }
}
CString 在 Unicode 建置下存 wchar_t,轉 std::string 需經 CW2A/CT2A;反之亦然。c_str() 返回指標隨 std::string 修改/銷毀失效,切勿 const char* p = str.c_str(); str.clear(); use(p);。ReleaseBuffer 導致記憶體洩漏或長度錯誤。atoi 無錯誤報告:atoi("abc") 返回 0 無法區分「真 0」與「解析失敗」,改用 strtol 或 std::stoi。現代 C++ 首選 std::to_string/std::stoi、stringstream、c_str() 三板斧;MFC/ATL 專案善用 CString 構造函式與 Format,配合 CT2A/CW2A 處理編碼。建立統一工具類 StringUtil 封裝上述邏輯,專案中統一調用,徹底告別轉換混亂。