课堂

scanf函数

C 语言笔记:scanf 函数

1. 基本用法

scanf 是 C 语言标准输入函数,用于从标准输入(通常是键盘)读取数据,并将读取的值存入指定变量。

#include <stdio.h>

int main(void)
{
    int a;
    scanf("%d", &a);
    printf("%d\n", a);
    return 0;
}

基本语法:

scanf("格式控制字符串", &变量1, &变量2, ...);
  • 格式控制字符串:指定输入数据的类型和读取规则。
  • &变量:取变量的地址,使 scanf 能够修改变量的值。
  • 字符数组等特殊情况不一定需要 &,例如 scanf("%s", str)。

2. 常用格式控制符

格式控制符 对应类型 说明
%d int 读取十进制整数
%f float * 读取 float 类型的数
%lf double * 读取 double 类型的数
%c char * 读取一个字符,包括空格、换行符
%s char * 读取字符串,遇到空白字符停止
%ld long * 读取 long 类型的整数
%lld long long * 读取 long long 类型的整数
%u unsigned int * 读取无符号整数

注意:scanf 中 %f 对应 float *,而 %lf 对应 double *;这与 printf 输出浮点数时的规则不同。

3. 一次读取多个变量

int a, b, c;
scanf("%d %d %d", &a, &b, &c);

输入:

10 20 30

结果:

  • a = 10
  • b = 20
  • c = 30

scanf 通常不要求输入必须位于同一行。它会按照格式依次读取数据,并自动跳过整数、浮点数等转换前的空白字符。

例如,以下输入也可以正确读取:

10
20
30

4. scanf 与空白字符

4.1 %d、%f 等会跳过前导空白

例如:

int n;
scanf("%d", &n);

输入:

   123

仍然会读取到 123。

4.2 %c 不会自动跳过空白

这是最容易出错的地方。

int n;
char a, b, c;

scanf("%d%c%c%c", &n, &a, &b, &c);

输入:

3 A B C

读取过程:

  1. %d 读取整数 3。
  2. 第一个 %c 读取空格。
  3. 第二个 %c 读取字符 A。
  4. 第三个 %c 读取空格。

因此,a、b、c 分别是空格、A、空格。

解决方法一:在格式控制符之间添加空格。

scanf("%d %c %c %c", &n, &a, &b, &c);

格式字符串中的空白字符会匹配并跳过输入中的连续空白,包括空格、换行符和制表符。

解决方法二:在 %c 前添加空格。

scanf("%d %c%c%c", &n, &a, &b, &c);

这里的空格会跳过 3 后面的空白,但后面三个 %c 仍然会连续读取字符,不跳过字符之间的空格。因此,这种写法只适用于你确定字符之间没有空白的情况。

5. %s 与字符串读取

char word[20];
scanf("%19s", word);
  • %s 读取连续的非空白字符。
  • %s 会自动在字符串末尾添加 '\0'。
  • word 是字符数组,因此不需要写 &word。
  • %19s 限制最多读取 19 个字符,为终止符预留一个位置。

例如,输入:

hello world

第一次读取后,word 保存 "hello",而不是整个 "hello world"。

如果需要读取包含空格的一整行,可以考虑使用 fgets。

6. scanf 的返回值

scanf 返回成功完成赋值的输入项数量。

例如:

int a, b, c;
int result = scanf("%d %d %d", &a, &b, &c);

如果成功读取三个整数,result 为 3。

如果只成功读取两个整数,result 为 2。

如果在任何赋值完成前遇到文件结束,可能返回 EOF。

常见用法:循环读取多组数据

int n, f1, a, b;

while (scanf("%d %d %d %d", &n, &f1, &a, &b) == 4)
{
    // 处理一组数据
}

适用于题目没有给出测试组数、要求持续读取到输入结束的情况。

循环条件保证只有成功读取四个整数时才处理这一组数据。

7. 常见错误总结

错误 原因 解决方法
忘记写 & scanf 需要变量地址 基本类型变量通常写 &变量
%c 读到空格或换行 %c 不跳过空白 在 %c 前加空格
%s 读入字符串时发生越界 缓冲区空间不足 使用 %Ns 限制读取长度
忽略返回值 输入可能不完整或格式错误 检查返回值是否等于预期赋值数量
误以为按行读取 scanf 通常按格式读取,而非按行读取 根据实际数据格式判断输入逻辑
scanf 读取失败后仍继续使用变量 变量可能未成功赋值 检查返回值后再使用数据