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