前言

这是一种不大常用的方法, 但是个人觉得很好用

在这里有所提及:

CppReference std::scanf,std::fscanf,std::sscanf

下面使用 scanf 来代指和 scanf 有类似功能的函数 ( scanf/sscanf/fscanf等 )

集合用法

简述

大家都知道 scanf/sscanf/fscanf 中可以以 %d %s %f 等作为占位符

但是有一种特殊的占位符 他的形式如: %[<Set>]

具体

其中<Set>的填入类似弱化版的正则表达式(但是比正则菜多了), 可以一次性定义多个格式, 按格式读

指定字符

可以指定读取特定的字符

例如: 想要读取 #+?$ 这四种字符中的任意一种 ( LG P2814 家谱 ), 那么我们可以这样:

char c;
scanf("%[#+?$]",&c);

他只有遇到规定的字符才会对变量 c 进行赋值, 否则将会一直按位读取 stdin 直到遇到或结束

范围读取

可以读取一个区间内的字符

例如: 想要读取一个字符的数字字符, 那么我们可以这样:

char c;
scanf("%[0-9]",&c);

那还想读一下多位的数字怎么办, 看这里:

char c[50];
scanf("%[0-9]",c);

如果使用类似 []] 的情况, 他会按照 ] 进行读取

显然, 范围读取也可以使用多重限定, 下面给出常用情况的例子:

  • %[A-Za-z] 所有的英语字母
  • %[A-Za-z0-9] 所有的英文字母和十进制数字
  • %[a-f0-9] 十六进制数字。

直到特定字符

我们可以使用 ^ 符号开头的限定符来规定哪些我们不需要读取

正常情况, 他会不断忽略输入流, 直到遇到这个字符

例如: 我们想读取到 \n 字符才结束, 可以这样

char l[50];
scanf("%[^\n]",l);

显然在这种情况, 遇到了 \n 字符的时候会直接结束, 所以字符串 l 的最后一位不是 \n

遇到类似 [^]] 的情况, 他会按照 ^] 进行读取

长度限定

显然, 集合也可以使用长度限定符

例如: stdin 为 123456 的情况下, 使用如下代码, 输出为 123

char buf[50];
scanf("%3[0-9]",buf);
printf("%s",buf);

抑制赋值符号

正常情况 scanf 需要一个指针来进行赋值

众所周知, 如果你只是想忽略特定格式的字符串, 可以使用 '*' 来抑制赋值

显然, 集合也可以使用抑制赋值标志 *

例如:

  1. 清空一个到 \n 的字符串, 那么我可以这么用:

    scanf("%*[^\n]");
  2. 清空一个由小写字母组成的字符串, 那么我可以这么写:

    scanf("%*[a-z]");

标签: none

仅有一条评论

  1. 谢谢

添加新评论