首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C/C++數值類型與字符串互轉完全指南:itoa、sprintf、stringstream對比

     編輯:關於C

數值與字符串轉換是C/C++開發中最高頻的操作之一。本文系統梳理int/long/float/double與string雙向轉換的四種主流方法,對比其適用場景、優缺點與注意事項。

一、數值 → 字符串

方法1:itoa / ltoa(C標準庫,非標準但廣泛支持)


#include <stdlib.h>

int a = 3;
long b = 23;
char buf1[32], buf2[32];

itoa(a, buf1, 10);  // 十進制,buf1 = "3"
ltoa(b, buf2, 10);  // buf2 = "23"
  • 優點:簡單直接,專為整數設計
  • 缺點:非ANSI/ISO標準(Microsoft擴展),不支持浮點數,緩衝區溢出風險
  • 適用:Windows平台快速整數轉字符串

方法2:sprintf / snprintf(C標準庫,通用)


#include <stdio.h>

int a = 3;
float b = 4.2f;
char buf[64];

sprintf(buf, "%d,%.2f", a, b);  // buf = "3,4.20"
snprintf(buf, sizeof(buf), "%d,%.2f", a, b); // 安全版本
  • 優點:標準C,支持所有類型,格式控制靈活(精度、進制、填充)
  • 缺點:sprintf不安全(緩衝區溢出),需用snprintf;類型不匹配導致未定義行為
  • 適用:C代碼、跨平台、性能敏感場景

方法3:ostringstream(C++標準庫,類型安全)


#include <sstream>
#include <string>

int a = 3;
float b = 4.2f;

std::ostringstream oss;
oss << a << "," << b;
std::string s = oss.str();  // s = "3,4.2"
  • 優點:類型安全(編譯期檢查),支持用戶定義類型(重載operator<<),無緩衝區溢出風險
  • 缺點:性能較低(流格式化開銷),代碼較冗長
  • 適用:C++項目、複雜格式化、類型安全優先場景

方法4:to_string(C++11標準庫,最簡潔)


#include <string>

std::string s1 = std::to_string(42);      // "42"
std::string s2 = std::to_string(3.14159); // "3.141590" (固定6位小數)
  • 優點:極簡API,標準C++11
  • 缺點:格式不可控(浮點數固定精度),無法指定進制
  • 適用:簡單調試輸出、不需精確格式控制場景

二、字符串 → 數值

方法1:atoi / atol / atof(C標準庫,簡單但無錯誤檢測)


#include <stdlib.h>

int a = atoi("32");      // 32
long b = atol("333");    // 333
double c = atof("23.4"); // 23.4
  • 致命缺陷:無法區分「轉換結果為0」與「轉換失敗」(如atoi("abc")返回0),無溢出檢測
  • 建議:生產代碼禁用,僅用於確知格式合法的簡單場景

方法2:strtol / strtod / strtoul(C標準庫,完整錯誤處理)


#include <stdlib.h>
#include <errno.h>
#include <limits.h>

char *endptr;
long val = strtol("333", &endptr, 10); // 十進制

if (endptr == str) { /* 無有效數字 */ }
if (*endptr != '\0') { /* 尾部有非數字字符 */ }
if (errno == ERANGE) { /* 溢出 */ }
  • 優點:標準C,完整錯誤報告(endptr、errno),支持任意進制(2-36)
  • 適用:C代碼、健壯性要求高、需檢測非數字字符場景

方法3:sscanf(C標準庫,格式化解析)


#include <stdio.h>

int a; float b;
sscanf("23 23.4", "%d %f", &a, &b); // 返回成功匹配項數
  • 優點:支持複雜格式解析,單次調用解析多個值
  • 缺點:格式字符串易出錯,返回值僅指示匹配數量,難以精確定位錯誤

方法4:istringstream(C++標準庫,類型安全)


#include <sstream>
#include <string>

std::istringstream iss("23 23.4");
int a; float b;
if (iss >> a >> b) { /* 成功 */ }
  • 優點:類型安全,流狀態檢查錯誤(fail()、bad()),支持用戶類型
  • 缺點:性能一般,默認按空白分隔,自定義分隔符需操作locale

方法5:stoi / stod 等(C++11標準庫,現代首選)


#include <string>

std::string s = "3.14";
size_t pos;
double d = std::stod(s, &pos); // pos = 4

// 異常處理
try {
    int i = std::stoi("abc");
} catch (const std::invalid_argument&) { /* 格式錯誤 */ }
catch (const std::out_of_range&) { /* 溢出 */ }
  • 優點:標準C++11,異常機制報錯,支持pos獲取解析位置,支持進制前綴(0x, 0)
  • 適用:現代C++項目首選,異常處理風格代碼

總結與選型建議

場景推薦方案備選
C代碼,整數轉字符串snprintfitoa(Windows)
C代碼,浮點數轉字符串snprintf-
C++11+,簡單轉換to_string / stoi/stodstringstream
C++,高性能/格式控制snprintf / fmt庫ostringstream
C代碼,健壯解析strtol/strtodsscanf
C++,異常風格錯誤處理stoi/stodistringstream

最佳實踐提醒

  • 永遠使用snprintf替代sprintf,指定緩衝區大小
  • 避免使用atoi/atof,轉用strtol/strtod或C++11函數
  • 浮點數轉字符串需精確控制精度時,優先snprintf("%.6f")或std::setprecision
  • 大數值解析必須檢查ERANGE或捕獲out_of_range
  • 跨平台代碼優先使用標準C/C++庫函數,避免依賴平台擴展

掌握各種轉換方法的特性與適用邊界,能顯著提升代碼的健壯性、可移植性與可維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved