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

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

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

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

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

相关文章

  • 由static_cast和dynamic_cast到C++对象占用内存的全面分析

    由static_cast和dynamic_cast到C++对象占用内存的全面分析

    下面小编就为大家带来一篇由static_cast和dynamic_cast到C++对象占用内存的全面分析。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 基于easyx的C++实现贪吃蛇

    基于easyx的C++实现贪吃蛇

    这篇文章主要为大家详细介绍了基于easyx的C++实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • Windows上CLion的配置步骤详解

    Windows上CLion的配置步骤详解

    这篇文章主要介绍了Windows上CLion的配置,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • C语言中的浮点数据类型

    C语言中的浮点数据类型

    这篇文章主要介绍了C语言中的浮点数据类型,文章会从处理带小数的数值的相关资料开始介绍,感兴趣的小伙伴的可以参考下面 文章的具体内容
    2021-10-10
  • Matlab实现同步子图视角的方法详解

    Matlab实现同步子图视角的方法详解

    这篇文章主要和大家分享三个可以Matlab中更简便实现同步子图视角的技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2022-06-06
  • 数据结构与算法中二叉树子结构的详解

    数据结构与算法中二叉树子结构的详解

    这篇文章主要介绍了数据结构与算法中二叉树子结构的详解的相关资料,需要的朋友可以参考下
    2017-04-04
  • C语言数组超详细讲解中篇三子棋

    C语言数组超详细讲解中篇三子棋

    数组是一组有序的数据的集合,本篇将带你结合数组来实现三子棋小游戏,上手实练更快的能够掌握数组使用,感兴趣的朋友来看看吧
    2022-04-04
  • C++中Cbitmap,HBitmap,Bitmap区别及联系

    C++中Cbitmap,HBitmap,Bitmap区别及联系

    这篇文章主要介绍了C++中Cbitmap,HBitmap,Bitmap区别及联系的相关资料,需要的朋友可以参考下
    2015-06-06
  • 常用排序算法的C语言版实现示例整理

    常用排序算法的C语言版实现示例整理

    这篇文章主要介绍了常用排序算法的C语言版实现示例整理,包括快速排序及冒泡排序等,基本上都给出了时间复杂度,需要的朋友可以参考下
    2016-03-03
  • C语言二分查找图文详解

    C语言二分查找图文详解

    折半查找法也叫做二分查找,顾名思义就是把数据分成两半,再判断所查找的key在哪一半中,再重复上述步骤知道找到目标key,这篇文章主要给大家介绍了关于C语言二分查找的相关资料,需要的朋友可以参考下
    2023-04-04

最新评论