养生
sscanf(scanf() VS cin:C++输入到底该用谁?结果可能让你惊讶!)

在 C++ 中,scanf()是一个来自 C 标准库 的输入函数,定义在 <cstdio>(或旧式的 <stdio.h>)头文件中。它用于从标准输入(通常是键盘)按照指定的格式读取数据,并存储到变量中。


一、基本语法

int scanf(const char* format, ...);
  • 返回值:成功读取并赋值的参数个数;如果发生错误或遇到文件结束(EOF),则返回 EOF(通常是 -1)。
  • format:格式化字符串,指定了要读取的数据类型和格式。
  • ...:可变参数,表示要接收输入数据的变量的地址(通常使用 &取地址符)。

二、常见用法示例

示例 1:读取一个整数

#include <cstdio>int main() {    int num;    printf("请输入一个整数: ");    scanf("%d", &num);  // 注意取地址符 &    printf("你输入的整数是: %d\n", num);    return 0;}

示例 2:读取多个不同类型的值

#include <cstdio>int main() {    int age;    float height;    char name[50];    printf("请输入你的姓名、年龄和身高(用空格分隔): ");    scanf("%s %d %f", name, &age, &height);    printf("姓名: %s\n", name);    printf("年龄: %d\n", age);    printf("身高: %.2f\n", height);    return 0;}

⚠️ 注意

  • 对于字符串(如 char name[50]),不需要加 &,因为数组名本身就代表地址。
  • 使用 %s时,遇到空白字符(空格、制表符、换行)就会停止读取,所以不适合读取包含空格的字符串。

三、常用的格式说明符(Format Specifiers)

说明符

对应类型

说明

%d

int

读取十进制整数

%i

int

同 %d,可识别不同进制

%u

unsigned int

无符号十进制整数

%f

float

单精度浮点数

%lf

double

双精度浮点数(注意!)

%c

char

读取单个字符

%s

char[]

读取字符串(到空白停止)

%x

int

十六进制整数

%o

int

八进制整数

⚠️ 对于 double类型,必须使用 %lf,而在 printf中则统一使用 %f(C++ 中 printf也接受 %lf,但标准只要求 %f)。


四、与 C++ 更推荐的输入方式对比

虽然 scanf()在 C++ 中仍然可用,但 C++ 更推荐使用 cin(来自 <iostream>),因为它更安全、更易用,且类型安全。

对比示例:

使用 cin读取输入:

#include <iostream>using namespace std;int main() {    int age;    float height;    string name;  // 需要 #include <string>    cout << "请输入你的姓名、年龄和身高: ";    cin >> name >> age >> height;    cout << "姓名: " << name << endl;    cout << "年龄: " << age << endl;    cout << "身高: " << height << endl;    return 0;}

优点

  • 不需要手动管理格式字符串;
  • 不需要取地址符 &(除了需要引用传递的特殊情况);
  • 更加类型安全,不容易出错。

五、注意事项

  1. 缓冲区问题
  2. scanf()不会处理输入缓冲区中的换行符,可能导致后续输入异常。比如在输入数字后跟字符串时容易出错。
  3. 解决方法:可以用 getchar()清除多余的回车,或者更推荐使用 cin/getline()。
  4. 安全性
  5. scanf()对输入长度没有自动检查,容易导致缓冲区溢出(尤其是 %s读取字符串时)。
  6. 更安全的替代品是 fgets()或者使用 C++ 的 std::string和 getline()。
  7. 格式匹配
  8. 用户输入必须严格符合格式字符串的要求,否则可能导致读取失败或程序行为异常。

六、总结

特性

scanf()

cin(C++方式)

来源

C 标准库 <cstdio>

C++ 标准库 <iostream>

类型安全

❌ 不安全

✅ 类型安全

易用性

需手动控制格式和地址

更直观,自动类型推导

缓冲区安全

❌ 容易溢出(特别是 %s)

✅ 更安全,尤其搭配 string

推荐程度

一般用于 C 或特定场景

✅ C++ 开发首选


七、如果你一定要用scanf(),推荐这样做:

  • 对于字符串,使用 %Ns(如 %49s)限制最大输入长度,防止溢出。
  • 混合输入时注意清除输入缓冲区。
  • 能用 C++ 的 cin/ getline()时优先使用它们。

如你有具体使用场景或遇到问题,欢迎继续提问,我可以给出更针对性的代码示例!


顶一下()     踩一下()

热门推荐

发表评论
0评