跳转到主内容
极星编程网:以代码为星,赴技术山海!

c++ scanf和printf用法_c++ C语言风格输入输出

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")
会直接读到换行符) 示例问题代码:
#include int main() { int x; char c; scanf("%d", x); // ❌ 缺少 &x,栈破坏 scanf("%c", &c); // ❌ 可能读到上个输入留下的 \n }
printf
的格式符和参数类型必须一一对应
printf
不做运行时类型检查,传错类型会导致输出乱码、截断甚至段错误(尤其在 64 位系统上): 立即学习 “ C语言免费学习笔记(深入) ”;
int
用
%d
,
long
用
%ld
,
long long
用
%lld
size_t
(如
vector::size()
返回值)应使用
%zu
,而非
%d
或
%lu
std::string::c_str()
可传给
%s
,但直接传
std::string
对象会编译失败(无 隐式转换 ) 错误示例:
std::vector v = {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
)是独立缓冲的。混用会导致: C函数速查手册(CHM版) C函数速查手册(CHM版) 下载 输出顺序错乱(
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: ACM/ICPC 等 OJ 平台要求极致输入速度(关闭同步后
scanf
比
cin
快约 2–3 倍) 对接遗留 C 接口,或日志函数只接受
printf
-style 格式串 需要精确控制浮点数输出格式(如
printf("%.6f", x)
比
std::fixed << std::setprecision(6)
更简洁) 但即便如此,也要确保: 所有格式符与参数类型完全匹配 不混用 C/C++ 风格流 对用户输入做容错处理(如检查
scanf
返回值是否等于期望读取项数) 例如安全读整数:
int x; if (scanf("%d", &x) != 1) { // 输入失败,处理错误 }
真正麻烦的不是语法,而是格式符和类型的隐式契约——它不报错,只在某个平台、某种优化级别下突然崩掉。

相关文章