C-Scanf连续调用多次并且存在%c的问题

问题现象:

当程序中存在多个scanf时,针对第一个scanf的输入,一般用户会以空白字符(空格、换行、tab、换页符)等结束。但若后面有一个scanf(“%c”,&ch),则刚才输入的空白字符会被此次的scanf读入,因此空白字符也是一个字符,此将导致ch为空。

原因解释:

scanf的工作原理:(一般情况,即格式串中没有其它字符)用户的任何输入将被保存在缓冲之中,当有scanf时,scanf则从此缓冲队列中读取字符,直至遇到空白字符或者是此字符不可能是本次的输入为止,并把此字符放回原队列,此字符成为队列的第一个字符。当下一次scanf被调用时,将从第一个字符读取,若此时为%d,%f,%g,%e等数据格式串,则可跳过空白字符,直至出现数字为止;若此时为%c等字符(串)格式串,则会把空白字符读入,并给此变量赋值。

另外,若读取到不可能是本格式串所代表的字符时,程序将异常退出。如scanf(“%d”,&num)时,输入kk。

解决方法:

处理格式串中的普通字符,scanf采取的动作依赖于这个字符是否为空白字符。

l 空白字符:当在格式串中遇到一个或多个连续的空白字符时,scanf从输入中重复读取空白字符直至遇到一个非空白字符(把该字符放回原处)为止。格式串中的空白字符的数量无关紧要,格式串中的一个空白字符可以与输入中任意数量(包括0个)的空白字符相匹配。

l 其它字符:当在格式串中遇到非空白字符时,scanf将把它与下一个输入字符进行比较。如果两个字符相匹配,那么scanf会放弃输入字符而继续处理格式串。如果两个字符不匹配,那么scanf会把不匹配的字符放回输入中,然后异常退出。例如,scanf(“%d/%d,&a,&b),输入是5/96,则a=5,b=96。

归纳总结:

(1)若格式串中没有其它字符,则读入可能是本变量的所有输入,直至明显不是本变量的输入。且非字符类型的格式串(如%d,%f,%g,%e)会跳过所有空白字符寻找第一个字符输入,但字符类型的格式串(如%c)不会跳过空白字符。

(2)若格式串中有其它字符,则分为空白字符与非空白字符讨论。

因此,上述问题可以使用scanf(“ %c”,&ch)解决。

时间: 2024-12-21 16:44:49

C-Scanf连续调用多次并且存在%c的问题的相关文章

连续调用scanf的问题总结

对于非常简单的scanf函数,一直使用,但是却是有很多的知识点没有掌握好,现总结如下: 1.多个scanf之后,后序以 scanf("%c",&c) 当程序连续调用scanf 函数的,前面的获得输入接收的时候,一般结束都是以一个空白字符(空格.enter),比如enter 结束输入:但是,当后面接着是还有一个以 scanf("%c",&a) 的时候,则上面输出 enter 作为结束符,就会被输入到a,从而导致了a 为空. (1)以%d 继续输入的时候

类的连续调用方法

class a{ private $b = 0; public function c( $Num = 0 ) { $this->b = $Num; return $this; //关键就在这里,有这条就可以连续调用了, } public function d($d) { $this->b = $this->b+$d; return $this; } public function e(){ echo $this->b; } } //接下来是调用 $Obj = new a; $Obj

AFN的实时网络监控 但是block连续调用了两次

[[AFNetworkReachabilityManager sharedManager] startMonitoring]; [[AFNetworkReachabilityManager sharedManager ] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case -1: NSLog(@"未知网络"); break; case 0: NSL

js实现函数的连续调用

用js的方式实现如jquery那样的方法连续调用 $("div").width(100).height(500).html(123); var obj = {}; obj.func1 = function () { console.log('func1'); return this; }; obj.func2 = function () { console.log('func2'); return this; }; obj.func1().func2(); 原文地址:https://w

一个简单的连续调用脚本部署代码的案例

先简单描述一下环境,Jenkins部署在私有云,从git拉取代码并编译后会调用脚本将jar包部署到阿里云的应用服务器.阿里云应用服务器无公网IP,通过跳板机登录.就产生了连续调用脚本,穿透跳板机部署到阿里云内网的需求. 服务器信息:**主机名称 IP ** git server 10.150.27.51 jenkins server 10.150.27.52 jump server 1.1.1.1/192.168.2.20 app server1 192.168.2.21 app server1

C++——类的成员函数的连续调用与返回值问题

一.返回值问题 1 #include <iostream> 2 3 using namespace std; 4 5 class X 6 { 7 public: 8 int a = 3; 9 X set1(int b) 10 { 11 a = b; 12 return *this; 13 } 14 }; 15 16 int main() 17 { 18 X x; 19 x.set1(6); 20 cout << x.a; 21 22 return 0; 23 } 此处set1函数的

【JavaScript】 模拟JQuery的连续调用函数

连续调用,了解调用主体 var zhangsan = { smoke: function () { console.log("Smoking..."); return this; }, drink: function () { console.log("drinking..."); return this; }, perm: function () { console.log("Perming..."); return this; } } zha

多个atomic类连续调用能否构成原子性?

答案是不能保证,具体可以参考下边案例: public class MyAtomic { AtomicInteger count = new AtomicInteger(0); public void test(){ for(int i=0;i<10000;i++){ /*此处模拟多个类连续调用:可能出现线程一拿到count为999,线程二拿到count为999, 这样会造成count进行多次+1,所以输出的结果会大于一千*/ if(count.get()<1000) { count.incre

WPF Loaded事件连续调用两次的问题

最近开发的一套系统中,在检查开发成员的代码时候,在Loaded事件中加上以下语句: this.Loaded -= new RoutedEventHandler(***_Loaded);这让我觉得有些奇怪.如是参照系统中的代码逻辑写了一个demo. MainWindow代码如下: private void Window_Loaded(object sender, RoutedEventArgs e) { TabItem item = new TabItem(); UserControl1 test