字符的不定输入之正则输入和gets( )函数

前言:

本篇文章讨论的不定输入,是旨在研究“任意个数的字符或整型都可以被成功读取,并存放在数组中”。也就是想输入多少就输入多少,且成功读取的 “输入方式”。

引例-牛客网OJ题

为了更好地说明这个问题,我们以一道牛客网的题目作引例。题目链接贴在这里

字符逆序__牛客网字符逆序icon-default.png?t=N7T8https://www.nowcoder.com/questionTerminal/cc57022cb4194697ac30bcb566aeb47b

题干如下: 

我们在前文中分析过这道题的解题方法,所有,简短洁说,在这里便不再过多赘述。

详情见: 

对多组输入while((scanf(“%c“,&ch)!=EOF)的整理和总结-CSDN博客文章浏览阅读1k次,点赞27次,收藏18次。判断是元音还是辅音_牛客题霸_牛客网KiKi开始学习英文字母,BoBo老师告诉他,有五个字母A(a), E(e), I(i),。题目来自【牛客题霸】这道题的基本思路很明确,将所有的元音字母作为元素定义一个字符数组arr[5],这时有人会说,不对呀,这不严谨,算上大小写应该是十个呀,为什么是arr[5]。https://blog.csdn.net/Isaiah_Cohen/article/details/136029902?spm=1001.2014.3001.5501

字符的不定输入

要知道,字符串可以视作字符数组来使用的,所以,对于字符的不定输入来说,方法比较简单,大致分为三种。

scanf("%s",arr)

这种,就比较普遍。也是平常做题中最常见的,和最常使用的。%s会一直读取到换行符(‘\n’)或者空格、制表符('\t')停止。并最终存放在目标数组arr 中。也就是说,结束标志('\0')也会一并保留到数组中,所以,大可放心的使用<string.h>下的库函数,不必担心存在数组越界的问题。不过要值得注意的是,在最开始创建数组时,数组arr 的大小一定要大于所要读取的字符个数,所以在创建使要看清题目要求,且要尽可能大。

劣势:上文中提到,scanf("%s",arr),读取时遇到空格就会停止读取,所以,在题例中存在空格的时候要尽量避免使用,而另谋他法。

gets(arr)

 在总结之前,不妨我们先看一看,gets( )函数本身。

gets( )

属于C标准库<stdio.h>

gets()函数 会读取整行输入行,直至遇到换行符,然后丢弃换行符,储存其余字符,并在字符末尾添加一个空字符使其成为C字符串。

函数原型

char* gets(char* str)

参数:指向储存输入内容地址的指针。

返回值:成功读取输入会返回储存输入内容的地址,发生错误或未读取任何非 '\n'字符则返回NULL(空指针)。

gets( )可以成功读取非‘\n’的任何字符,所以这就弥补了scanf("%s",arr),读取空格和制表符会失效的问题。此外,他会丢弃换行符,储存其余字符,并在字符末尾添加一个空字符使其成为C字符串,所以,gets( )函数存放的数组也可以放心的使用<string.h>下的库函数。

劣势:不过,gets( )是一个危险的函数。在使用时要更加谨慎地使用。

当gets()函数的参数是有限大小的字符数组时,其唯一的参数是该字符数组首元素的地址(即指向该字符串首元素的指针),它无法检查数组的空间是否足够储存所有输入行。如果输入的字符串过长,会导致缓冲区溢出,多余的字符会超出指定的目标空间。

如果超出的字符仅占用了尚未使用的内存,就不会立即出现问题;如果它们修改了程序中的其他数据,会导致程序异常或中止;或其他情况。

scanf("%[^\n]",arr)

不妨我们先认识一下,何谓正则表达式吧。

正则表达式

正则表达式是一种字符串匹配的模式,这是因为正则本质,是使用贪婪算法,即算法可能多的匹配字符。

接下来,我们浅浅了解一下%[^\n]的各个组成部分。

%[ ]表示 一个字符集,表示字符和文字的数据集合,我们常见的的Ascii码也是字符集的一种。

^ 表示遇到该内容停止读取。

例如,“%[^=]” 表示读入任意多的字符,直到遇到"=“停止。

%[0-9]表示只读入’0’到’9’之间的字符,遇到非数字就会停止。

%[a-zA-Z]表示只读入字母,遇到非字母就停止。

其中,“-”则是范围连接符,用来连接有序的字符

了解到上面,我们就可以知道,%[^\n]表示遇到换行为止。

此外,我们还可以,对正则输入进行修饰一番。

比如,在其前加整数 “n”来限制输入的个数。

“%ns”,表示读入的字符串最长不超过n,然后在末尾补’\0’。
%nf ,读入的浮点数最多有n位整数,位数多于n则截断。
“%n[a-z]” 读入最多n个字符,如果遇到非a-z的字符则停止。

“%n[^\n]” 读入回车号”\n"前的至多n个字符。

或者,使用*表示该输入项读入后不赋予任何变量,即,表示跳过对应字符。通常,*并不会单独出现,常与%同时出现。构成忽略匹配的字符  "%*"

比如“%*[a-z]”,忽略匹配[a-z]的字符。

%[^\n]%*c,表示遇到换行符停止 ,%*c的作用是吸收换行符。

因此,可以把%*看作%的兄弟,只是%是读入到变量,%*是跳过。

这里我们不过多赘述,详情见:

正则表达式语法大全_正则语法-CSDN博客文章浏览阅读7.4w次,点赞69次,收藏628次。前言:一般开发中都会接触到正则表达式,作为一名合格的前端,也应该了解一下正则表达式编写原则,便于自己也能快速编写想要的正则表达式。_正则语法https://blog.csdn.net/sinat_34626741/article/details/123883244?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170935997816800197053369%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170935997816800197053369&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-123883244-null-null.142%5Ev99%5Econtrol&utm_term=%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%A4%A7%E5%85%A8&spm=1018.2226.3001.4187

从以上我们可以得知, scanf("%[^\n]",arr),将一直读取到回车符结束,包括制表符和空格。并统统将其存放到arr中,再在其后补 “\0”,所以,也可以大可放心地使用<string.h>下的库函数。并不会造成数组越界的问题。

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值