C++中不推荐使用scanf/printf,因其缺乏类型安全、易因格式符与参数类型不匹配导致崩溃或错误;应优先使用cin/cout,并在必须使用时严格校验格式符、避免混用流、检查返回值。
在 C++ 中直接用
和
是可行的,但不是推荐做法——它们属于 C
标准库
(
),不支持 C++ 类型安全、重载或流操作语义,容易因格式符错配导致未定义行为。
为什么
容易崩溃或读错数据
要求格式字符串与变量地址严格匹配,且不检查类型。常见错误包括:
忘记加
取地址(如对
写成
)
用
读
(应为
)或
(应为
,但变量必须是
,不是
)
输入缓冲区残留(如前一个
后用户多按了回车,下一个
会直接读到换行符)
示例问题代码:
的格式符和参数类型必须一一对应
不做运行时类型检查,传错类型会导致输出乱码、截断甚至段错误(尤其在 64 位系统上):
立即学习
“
C语言免费学习笔记(深入)
”;
用
,
用
,
用
(如
返回值)应使用
,而非
或
可传给
,但直接传
对象会编译失败(无
隐式转换
)
错误示例:
正确写法:
混用
和
前必须同步关闭
默认情况下,C++ 流(
/
)和 C 流(
/
)是独立缓冲的。混用会导致:
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
输出顺序错乱(
立即刷屏,
可能延迟)
输入阻塞(
后再用
读字符,可能跳过预期输入)
解决方法:在
开头加
注意:
一旦调用该设置,就不能再混用和
(否则行为未定义)。若已用
,就全程用 C 风格;若用
,就别碰
。
替代方案:什么时候真该用
仅在以下场景可考虑保留 C 风格 I/O:
ACM/ICPC 等 OJ 平台要求极致输入速度(关闭同步后
比
快约 2–3 倍)
对接遗留 C 接口,或日志函数只接受
-style 格式串
需要精确控制浮点数输出格式(如
比
更简洁)
但即便如此,也要确保:
所有格式符与参数类型完全匹配
不混用 C/C++ 风格流
对用户输入做容错处理(如检查
返回值是否等于期望读取项数)
例如安全读整数:
真正麻烦的不是语法,而是格式符和类型的隐式契约——它不报错,只在某个平台、某种优化级别下突然崩掉。
scanfprintfscanfscanf&int x;scanf("%d", x)%dlong long%lldfloat%ffloat*double*scanf("%d")scanf("%c")#include
int main() {
int x;
char c;
scanf("%d", x); // ❌ 缺少 &x,栈破坏
scanf("%c", &c); // ❌ 可能读到上个输入留下的 \n
} printfprintfint%dlong%ldlong long%lldsize_tvector::size()%zu%d%lustd::string::c_str()%sstd::stringstd::vector v = {1,2,3};
printf("size: %d\n", v.size()); // ❌ %d 匹配 int,但 size() 返回 size_t → 输出可能为负或截断 printf("size: %zu\n", v.size()); // ✅cin/coutscanf/printfcincoutstdinstdoutprintfcoutcin >> xscanfmain()std::ios::sync_with_stdio(false); // 解绑 cin/cout 与 stdin/stdout
cin.tie(nullptr); // 解绑 cin 与 coutcinscanfscanfcinscanfscanf/printfscanfcinprintfprintf("%.6f", x)std::fixed << std::setprecision(6)scanfint x;
if (scanf("%d", &x) != 1) {
// 输入失败,处理错误
}