#include <stdio.h>

描述

C 库函数 scanf(scan formatted) 从标准输入 stdin 读取格式化输入,并在指定的参数中写入结果。

声明

int scanf (const char *format, ...);

参数

  • 空白字符:函数将读取并忽略在下一个非空白字符之前遇到的任何空白字符(空白字符包括空格、换行和制表符[1])。
  • 非空白字符,格式说明符(%除外):每个格式字符串中的这种字符处理来自输入流的准确同一字符,或若它与流的下个字符比较不相等则导致函数失败。
  • 格式说明符:由初始百分号 (%) 形成的序列表示格式说明符,用于指定要从流中检索并存储到附加参数指向的位置的数据的类型和格式。
  • 附加参数:输入数据的存储位置。为了存储此输入数据,scanf 需要知道变量的内存位置。

scanf格式说明符遵循以下原型:%[*][width][length]specifier

格式说明符

格式说明符的解释及其相应参数的类型:

转换指示符 描述
i 匹配一个整数
d or u 匹配一个十进制整数u 匹配无符号十进制整数
o 匹配一个无符号八进制数
x, X 匹配一个无符号十六进制整数
a, f, e, g 匹配一个浮点数
c 匹配一个字符字符的序列若使用了宽度指示符,则匹配准确的宽度个字符
s 匹配非空白字符的序列(一个字符串)若使用宽度指示符,则至多匹配宽度个字符,或匹配到首个提前出现的空白符前。总是在匹配的字符后存储一个空字符
p 匹配定义一个指针的实现定义的字符序列
[characters] 匹配一个来自集合的字符的非空字符序列
[^characters] 匹配所有不在集合中的字符
n 返回迄今读取的字符数
% 匹配字面 %

n 外,任何说明符都应至少消耗一个字符。否则匹配失败,输入结束。

格式说明符还可以包含子说明符:星号(*)、宽度长度(按此顺序),它们是可选的并遵循以下规范:

子说明符 描述
* 可选的起始星号表示数据将被读取但会忽略(即它不存储在参数指向的位置)
宽度 指定当前读取操作中要读取的最大字符数(可选)
长度 hh、h、l、ll、j、z、t、L之一(可选)
这会改变相应参数所指向的存储的预期类型

返回

scanf 返回三种类型的值:

  • > 0:成功转换和赋值的值的数量。
  •     0:未分配任何值。
  • < 0:在进行任何分配之前遇到读取错误或到达文件结尾 (EOF)。

使用

非空白字符

1
2
3
// 输入 First:1Second:2Third:3
scanf("First:%dSecond:%dThird:%d", &a1, &a2, &a3);
// a1=1, a2=2, a3=3

指定宽度

1
2
3
// 输入 20231112
scanf("%4d%2d%2d", &year, &month, &day);
// year=2023, month=11, day=12

忽略输入

当题目所给输入中只有部分有用时,可以选择忽略部分输入

例题

取石子[2]

AliceAliceBobBob 轮流在一个石子堆取石子,谁先无法操作谁输。AliceAlice 先手。

给定两个正整数 a,ba,bAliceAlice 每次能拿走 a2x2+ax+1a^2x^2+ax+1 个石子,BobBob 每次能拿走 b2y2+by+1b^2y^2+by+1 个石子。(xxyy 是由 AliceAliceBobBob 自己确定的非负整数,每次的 xx 可以不同,每次的 yy 可以不同,但是每次取走的石子数不能超过总石子数。)

现在有 TT 组询问,每组询问给定 a,ba,b,这个石子堆的石子数 nn,问在两人都足够聪明的前提下,谁能取得胜利。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%*d%*d%d", &n);
if (n % 2) printf("Alice\n");
else printf("Bob\n");
}
return 0;
}

引用

- [1] cplusplus-isspace
- [2] 第四届辽宁省大学生程序设计竞赛(正式赛) H题