C++ 怎么把数字转换成字符串?附 4 种方法讲清楚

编程狮(w3cschool.cn) 2026-08-20 14:32:09 浏览数 (24)
反馈

C++ 怎么把数字转换成字符串?

你在写日志、拼文件名或者做界面文本时,一定碰到过这种情况:程序算出了一个整数或小数,你得把它变成一串字符才能拼进一段话里。C++数字转字符串,最省事的做法是用 to_string,要控制小数位数就用 stringstream,要和 C 语言老代码兼容就用 sprintf,非标准的 itoa 则不推荐。

本文基于 C++11 及以上标准验证,覆盖 to_stringstringstreamsprintfitoa 四种做法,并附上横向对比和踩坑清单。看完你不仅能写出正确的转换代码,还能理解它们各自的适用边界,下次拼字符串可以自己选型。今天这篇文章,编程狮就把这块讲透。

一、先搞清楚为什么要做数字转字符串

所谓 C++数字转字符串,指的是把一个 intdouble 等数值类型,变成 std::string 或 C 风格字符串,方便拼接、输出或存储。例如把成绩 95 变成 "95",再拼成 "你的成绩是 95 分"

之所以要专门讲,是因为 C++ 里数值和字符串是两套体系,不能直接用 +intstring 拼在一起,必须先转换。这种 类型转换 在日志、报表、网络协议组包里几乎天天用到。

⚠️ 注意:很多新手会写出 string s = "分数" + 95; 这样的代码,编译器会直接报错,因为字符串字面量和整数不能相加。必须先转成字符串再拼接。

1.1 C++ 和 C 的转换有什么关系

C++ 完全兼容 C 语言,所以 C 的 sprintf 在 C++ 里也能用。C 语言教程 里讲的标准库函数,在 C++ 项目里同样可以调用;而 to_stringstringstream 是 C++ 后来提供的更现代、更安全的写法,新项目优先用它们。

二、方法一:to_string(最省事)

std::to_string 是 C++11 引入的标准函数,支持 intdoublelong 等常见数值类型,直接返回 std::string,不用管格式细节,是日常快速转换的首选。它最大的优点是「零配置」:你不需要告诉它小数保留几位、整数补不补零,丢进去就能拿到字符串,特别适合日志、调试输出这类对格式要求不高的场景。

不过也正因为零配置,当你真正需要控制格式时它会「帮倒忙」。比如想把 3.14159 只显示两位,直接用 to_string 会得到一长串 3.141590,后面那些 0 往往不是你想要的。这种时候就要往下看 stringstream 了。

#include <iostream>
#include <string>


int main() {
    int score = 95;
    double pi = 3.14159;
    std::string s1 = std::to_string(score);   // "95"
    std::string s2 = std::to_string(pi);      // "3.141590"


    std::cout << "成绩是 " + s1 + " 分" << std::endl;
    return 0;
}

上面这段做的是:把整数 95 和小数 pi 分别转成字符串,再和中文拼起来输出。注意 to_string 对小数默认保留六位,想要更短要做额外处理。

顺便提一句,to_string 是「尽力而为」的转换:它不会因为你给了 double 就报错,也不会因为数值太大而抛异常,只是结果可能比你预期的更长。所以在金额、坐标这类对格式敏感的场景,别指望它一步到位,老老实实交给 stringstream 更稳。

💡 小提示:to_string 返回的已经是 std::string,可以直接参与 + 拼接;但它对格式几乎没有控制力,定格式的需求要交给下面的 stringstream

三、方法二:stringstream(可控格式)

如果你要控制小数位数、补零、对齐,用 std::stringstream 最灵活。它像 cout 一样往里塞数据,最后转成字符串,格式化能力和 cout 完全一致。

#include <iostream>
#include <sstream>
#include <iomanip>


int main() {
    double pi = 3.14159;
    std::stringstream ss;
    ss << std::fixed << std::setprecision(2) << pi;
    std::string s = ss.str(); // "3.14"


    std::cout << s << std::endl;
    return 0;
}

上面这段做的是:用 fixedsetprecision(2) 把小数固定保留两位,得到 "3.14"。语法细节记不住时,C++ 教程 的流操作章节可以随手查。

⚠️ 注意:stringstream 每次复用前要调用 ss.str("")ss.clear() 清空,否则旧内容会残留在里面,导致多次转换结果串味。

四、方法三与四:sprintf 与 itoa(兼容 C)

sprintf 来自 C 标准库,按格式符把数字写进字符数组,兼容老代码;itoa 则专门把整数转成字符数组,但不是 C++ 标准函数,可移植性差,不推荐在新项目里用。

#include <cstdio>


int main() {
    char buf[32];
    int n = 42;
    sprintf(buf, "%d", n);   // buf 里是 "42"
    // itoa(n, buf, 10);    // 非标准,部分编译器不支持
    return 0;
}

上面这段做的是:用 sprintf%d 格式把整数写进 buf。它功能强,但要自己管缓冲区大小,写太长会溢出。和字符串转换相对,如果你要做的是在字符串里找内容,可以看这篇 C++ 怎么在字符串里查找子串

4.1 为什么更推荐 snprintf

sprintf 的隐患在于它不检查 buf 能不能装下结果。如果数字位数超过 buf 长度,就会往后面的内存写,轻则数据错乱,重则程序崩溃。C99 起提供的 snprintf 多一个「最多写多少字节」的参数,能从根本上避免溢出:

char buf[32];
snprintf(buf, sizeof(buf), "%d", n); // 最多写 31 个字符 + 结尾 \0

多写这行约束,代码就安全了一大截,所以新代码里优先用 snprintf 而不是 sprintf

方法 返回类型 格式可控 安全性 适用场景
to_string string 快速转换
stringstream string 需要定格式
sprintf char[] 中(需管缓冲) 兼容 C
itoa char[] 低(非标准) 仅旧代码

表:四种转换方法横向对比。快速转换用 to_string,需要定格用 stringstream,兼容老 C 代码用 sprintf,新项目避免 itoa。

C++ 数字转字符串的四种方法怎么选?

五、踩坑清单

把读者最容易卡住的三个点列出来:

  • 整数不能直接拼字符串"分" + 95 会编译报错,务必先 to_string
  • to_string 小数位数多:默认六位,需要截断用 stringstream
  • sprintf 缓冲区溢出buf 太小而数字太长会写越界,建议用更安全的 snprintf
  • itoa 平台差异itoa 连缓冲区大小参数都没有,且不是标准函数,在需要跨平台时尽量避开,用 to_stringsnprintf 替代。

总结

C++数字转字符串,快速转换用 to_string,要定格式用 stringstream,兼容老 C 代码用 sprintf。新手优先前两种,更安全也更现代。

要点带走:

  • 数值和字符串不能直接相加,先转再拼;
  • 小数要控制位数就用 stringstream
  • 新项目尽量别用 itoa,它不是标准函数。

把 C++基础 里的流与标准库打牢,再去了解 C 语言里的格式化输出,这种 类型转换 的思路在混合语言项目里会反复用到。

一句话选型:临时拼个整数用 to_string 最省心;要定小数位数、补零、对齐就上 stringstream;只有要和维护多年的 C 老代码保持一致时才碰 sprintf/snprintf,且记得带上缓冲区大小。

延伸学习

想把 C++ 字符串处理这块系统补齐,可以按这个顺序来:

  1. 想横向看各语言定位,可以看 5 大编程语言对比,选语言时更有底气;
  2. 想动手练,C++ 入门课程 是边学边写的形式,适合巩固。

常见问题

Q:为什么 "分数" + 95 会编译报错?
A:因为字符串字面量是 const char*string,整数 95 是数值,两者类型不同不能直接相加。必须先 to_string(95) 转成字符串再拼接。

Q:to_string 的小数怎么只保留两位?
A:to_string 本身不支持,要改用 stringstream 配合 fixedsetprecision(2),如正文第三节所示。

Q:itoa 为什么不建议用?
A:因为 itoa 不是 C++ 国际标准函数,在部分编译器(如某些平台的 GCC)上根本没有,写了代码换平台可能编不过。优先用 to_stringsprintf

Q:sprintf 和 snprintf 该用哪个?
A:优先 snprintf,它多一个缓冲区大小参数,能防止数字过长导致的内存溢出,比 sprintf 更安全。

C++

0 人点赞