scanf,sscanf和fscanf函数区别

1. scanf(标准输入)

功能:从标准输入(stdin,通常是键盘)读取格式化数据。

//原型:
int scanf(const char *format, ...);

//示例
int num;
scanf("%d", &num);  // 从键盘读取整数

特点

  • 适用于交互式输入(如用户键盘输入)。
  • 容易因缓冲区问题导致错误(如换行符残留)。
  • 不安全,可能导致缓冲区溢出(如 %s 读取字符串时不检查长度)。

2. fscanf(文件输入)

功能:从指定的文件流(FILE*)读取格式化数据。

// 原型:
int fscanf(FILE *stream, const char *format, ...);

// 示例:
FILE *file = fopen("data.txt", "r");
int num;
fscanf(file, "%d", &num);  // 从文件读取整数
fclose(file);

特点

  • 适用于从文件读取结构化数据(如配置文件、日志文件)。
  • 返回值可检测是否成功读取(如文件结束时返回 EOF)。
  • scanf 一样,存在缓冲区溢出风险。

3. sscanf(字符串输入)

功能:从字符串(const char*)读取格式化数据。

//原型
int sscanf(const char *str, const char *format, ...);

// 示例
char line[] = "42 3.14 hello";
int num;
float f;
char str[20];
sscanf(line, "%d %f %s", &num, &f, str);  // 从字符串解析数据

特点

  • 适用于解析字符串(如解析 fgets 读取的行)。
  • scanffscanf 更安全,因为输入来源是内存中的字符串,无溢出风险。
  • 常用于数据转换(如将字符串转为数字)。

三者的核心区别

函数

数据来源

典型用途

安全性

scanf

标准输入(键盘)

交互式输入

❌ 不安全

fscanf

文件(FILE*

读取文件数据

❌ 不安全

sscanf

字符串(char*

解析字符串(如 fgets 的输入)

✅ 较安全

使用场景对比

1. 从键盘输入(scanf

int age;
printf("please input age:");
scanf("%d", &age);  // 直接从键盘读取

问题

  • 如果输入非数字(如 abc),会导致无限循环或错误。
  • 换行符可能残留在缓冲区,影响后续输入。

改进方案
fgets + sscanf 替代:

int age;
char input[100];

printf("please input age\n");
fgets(input, sizeof(input), stdin); // 先读取一行
sscanf(input, "%d", &age);          // 再从字符串解析

printf("input age is: %d\n", age);

2. 从文件读取(fscanf

FILE *file = fopen("data.txt", "r");
int num;
int count = fscanf(file, "%d", &num);
while ((count != EOF) && (count != 0)) // 0 is meet unmatch data
{
    printf("input date is %d, count = %d\n", num, count);
    count = fscanf(file, "%d", &num);
}
fclose(file);

适用场景

  • 读取格式化的文件数据(如每行一个数字)。

3. 从字符串解析(sscanf

char data[] = "Alice 25 80.5";
char name[50];
int age;
float score;
sscanf(data, "%s %d %f", name, &age, &score);

适用场景

  • 解析命令行参数、网络数据或文本文件的行。

安全性对比

函数

缓冲区溢出风险

换行符问题

推荐使用场景

scanf

高(%s 不限长度)

有(\n 残留)

安全性低,简单输入

fscanf

高(同 scanf

无(文件无交互)

读取格式化文件

sscanf

低(字符串长度已知)

解析字符串

最佳实践

  1. 避免直接用 scanf
    • fgets + sscanf 组合更安全。
char input[100];
fgets(input, sizeof(input), stdin);  // 安全读取一行
int num;
sscanf(input, "%d", &num);           // 安全解析
  1. 文件读取时检查 fscanf 返回值

防止文件格式错误:

while (fscanf(file, "%d", &num) == 1) { ... } // add check return is 0 or not
  1. sscanf 的高级用法

跳过部分数据:

sscanf("2023-12-31", "%d-%d-%d", &year, &month, &day);

限制字符串长度:

char name[10];
sscanf(data, "%9s", name);  // 最多读取 9 个字符
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值