C语言scanf语句吃掉回车或者空格问题及解决

 更新时间:2022年11月14日 15:23:43   作者:Z小旋  
这篇文章主要介绍了C语言scanf语句吃掉回车或者空格问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

问题描述

我们经常在C语言输入的时候,会发现scanf讲空格或者回车“吃掉”了,导致程序的运行结果与预期不一致

以下面一个简单例子为例

 #include<stdio.h>
 char str[10];
 int main()
 {
    int i;
	for(i=0;i<10;i++)
	{
		scanf("%c",&str[i]);		
	 } 
		for(i=0;i<10;i++)
	{
		 printf("%c",str[i]);
	 }
	 	return 0;
 }

这个程序,获取10个数,然后打印出来

如果我们正常的输入10个字符,打印正常

ru'guo

如果我们输入a,然后回车,再输入b,再回车… ,结果只能输入5个字符,这就是我们经常说的Scanf吃掉了你的回车

那么我们首先来了解一下scanf语句:

scanf

scanf()函数是格式输入函数,即按用户指定的格式从标准输入设备(键盘) 上把数据输入到指定地址的变量中。

读取方式:

一般格式为:scanf(格式控制,地址列表) 也就是scanf("%?",&?); 可以读取相对于类型的数值并且存储到制定变量,并且可以读取多个数值,如数字,字符,字符串等 ,每次用到scanf‘时,他都会从数据缓存区读取一个或多个字符,并存入相对应的变量中

注意:

  • scanf()在读取数字时会跳过空格、制表符和换行符!
  • %c只能输出或输入一个字符,%s输出的是一串字符还有就是char a; string s;输入的时候scanf("%c",&a);这里的&不能少,而scanf("%s",s);这里不能有&符号

重点:

scanf遇到 回车(enter),空格,TAB 就会结束一次输入,空格不会接收

并且, scanf在一次输入结束后,不会舍弃最后的回车符(即回车符会残留在数据缓冲区中)

看下方程序

#include <stdio.h>
int main(){
    char c1,c2;
    scanf("%c %c",&c1,&c2);   //这里有一个空格
    printf("%d %d\n",c1,c2);
 
    scanf("%c%c",&c1,&c2);  //这里没有空格
    printf("%d %d\n",c1,c2);
    return 0;
}

第一次输入a和b正常,没有问题,但是第二次就出现问题了,

scanf单字符输入时规定只接收一个字符,所以第一次输入a b 时 ,第一个scanf("%c %c")之间有一个空格,所以在输入字符a之后,我们可以输入空格,enter,,scanf都会自动忽略它(那个空格会读取停止字符并释放掉),所以第一次输入正常,但它却把回车符也作为字符对待的。

在我们输入完b之后按回车(Enter),这个回车符是放在缓冲区的,并且不会舍弃最后的回车符此时的数据缓存区中还残存着一个回车符,

第二次调用scanf("%c%c",&c1,&c2);是从缓冲区中取两个字符,首先把第一次调用scanf("%c%c",&c1,&c2);后输入的回车当作输入字符赋值给c1 ,之后把a赋值给了c2

这就在输入逻辑上造成了混乱。

我们这样改一下

#include <stdio.h>
int main(){
    char c1,c2;
    scanf("%c %c",&c1,&c2);   //这里有一个空格
    printf("%d %d\n",c1,c2);
 
    scanf(" %c %c",&c1,&c2);   //这里也有了空格
    printf("%d %d\n",c1,c2);
    return 0;
}

第二个scanf中添加了两个空格 然后我们正常输入

scanf(" %c",&c)前面这个空格(换成\n或者\t也可以),这样就把缓冲区中的回车当成第一个字符,读取后丢掉 

可以很好理解scanf中 空格的作用

空格( )即为读取一个结束字符然后丢掉,而普通的字符不受影响

用好之后可以避免很多程序BUG

那么现在各位应该知道上方的程序怎么改了

在对应位置加好空格就可以了,

这个问题的解决虽然简单,但是整个问题出现与解决的原因,才是我们需要学习的,不能只拘束与添加一个空格,而应该清楚的明白其内部的原理,这是我们学习所必须的一个品质。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C语言深入讲解内存操作问题

    C语言深入讲解内存操作问题

    程序运行的目的是为了得到特定的结果,计算机本质上是用于计算的,既然是用于计算,就需要参与计算的数据,那这些数据就存储在内存中,计算之前参与运算的数据以及运算之后得到的数据,都存储在内存中,所以对内存操作的掌握就尤为重要,下面我们一起来看看
    2022-04-04
  • 浅谈C语言数组元素下标为何从0开始

    浅谈C语言数组元素下标为何从0开始

    很多同学可能在学习数组时会有这个疑问,下标为什么不从1开始呢?本文主要介绍了浅谈C语言数组元素下标为何从0开始,感兴趣的可以了解一下
    2022-01-01
  • C++小游戏BrickHit实例代码

    C++小游戏BrickHit实例代码

    本文通过实例代码给大家介绍了C++小游戏BrickHit的相关资料,需要的朋友可以参考下
    2018-02-02
  • 如何用C写一个web服务器之I/O多路复用

    如何用C写一个web服务器之I/O多路复用

    本文主要介绍了如何用C写一个web服务器之I/O多路复用,本次选择了 I/O 模型的优化,因为它是服务器的基础,这个先完成的话,后面的优化就可以选择各个模块来进行,不必进行全局化的改动了。
    2021-05-05
  • C语言中如何利用循环嵌套输出一个菱形

    C语言中如何利用循环嵌套输出一个菱形

    这篇文章主要介绍了C语言中如何利用循环嵌套输出一个菱形问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C++面试题之数a、b的值互换(不使用中间变量)

    C++面试题之数a、b的值互换(不使用中间变量)

    这篇文章主要介绍了不使用中间变量,C++实现数a、b的值互相转换操作,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • C语言中动态内存分配malloc、calloc和realloc函数解析

    C语言中动态内存分配malloc、calloc和realloc函数解析

    C语言跟内存申请相关的函数主要有 alloca、calloc、malloc、free、realloc等,下面这篇文章主要给大家介绍了关于C语言中动态内存分配malloc、calloc和realloc函数的相关资料,需要的朋友可以参考下
    2022-03-03
  • 利用C/C++实现较完整贪吃蛇游戏

    利用C/C++实现较完整贪吃蛇游戏

    这篇文章主要为大家详细介绍了利用C/C++实现较完整贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Qt槽函数会被执行多次的问题原因及解决方法

    Qt槽函数会被执行多次的问题原因及解决方法

    本文主要介绍了Qt槽函数会被执行多次的问题原因及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • C++中小数点输出格式(实例代码)

    C++中小数点输出格式(实例代码)

    下面小编就为大家带来一篇C++中小数点输出格式(实例代码)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06

最新评论