scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。 

        ① 遇空格、“回车”、“跳格”键。 

        ② 遇宽度结束。 

        ③ 遇非法输入。
问题二:scanf()函数不能正确接受有空格的字符串?如: I love you!


#include <stdio.h> 

int main() 



    char str[80]; 

    

    scanf("%s",str); 

    printf("%s",str);
    return 0; 

}
输入:I live you! 

输出:I
       scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。 

        ① 遇空格、“回车”、“跳格”键。 

        ② 遇宽度结束。 

        ③ 遇非法输入。
所以,上述程序并不能达到预期目的,scanf()扫描到"I"后面的空格就认为对str的赋值结束,并忽略后面的"love you!".这里要注意是"love you!"还在键盘缓冲区(关于这个问题,网上我所见的说法都是如此,但是,我经过调试发现,其实这时缓冲区字符串首尾指针已经相等了,也就是说缓冲区清空了,scanf()函数应该只是扫描stdin流,这个残存信息是在stdin中)。我们改动一下上面的程序来验证一下:
#include <stdio.h> 

int main() 



    char str[80]; 

    char str1[80]; 

    char str2[80]; 

    

    scanf("%s",str);/*此处输入:I love you! */ 

    printf("%s",str); 

    sleep(5);/*这里等待5秒,告诉你程序运行到什么地方*/ 

    scanf("%s",str1);/*这两句无需你再输入,是对键盘盘缓冲区再扫描   */ 

    scanf("%s",str2);/*这两句无需你再输入,是对键盘盘缓冲区再扫描    */ 

    printf("/n%s",str1); 

    printf("/n%s",str2); 

    return 0; 

}
输入:I love you! 

输出:I 

      love 

      you!
好了,原因知道了,那么scanf()函数能不能完成这个任务?回答是:能!别忘了scanf()函数还有一个 %[] 格式控制符(如果对%[]不了解的请查看本文的上篇),请看下面的程序:
#include "stdio.h" 

int main() 



    char string[50]; 

    

     /*scanf("%s",string);不能接收空格符*/ 

     scanf("%[^/n]",string); 

     printf("%s/n",string); 

     return 0; 

}
问题三:键盘缓冲区残余信息问题


#include <stdio.h> 

int main() 



    int a; 

    char c;
    do 

    { 

        scanf("%d",&a); 

        scanf("%c",&c); 

        printf("a=%d     c=%c/n",a,c); 

        /*printf("c=%d/n",c);*/ 

    }while(c!='N'); 

}
   scanf("%c",&c);这句不能正常接收字符,什么原因呢?我们用printf("c=%d/n",c);将C用int表示出来,启用printf("c=%d/n",c);这一句,看看scanf()函数赋给C到底是什么,结果是 c=10 ,ASCII值为10是什么?换行即/n.对了,我们每击打一下"Enter"键,向键盘缓冲区发去一个“回车”(/r),一个“换行"(/n),在这里/r被scanf()函数处理掉了(姑且这么认为吧^_^),而/n被scanf()函数“错误”地赋给了c.
解决办法:可以在两个scanf()函数之后加个fflush(stdin);,还有加getch(); getchar();也可以,但是要视具体scanf()语句加那个,这里就不分析了,读者自己去摸索吧。但是加fflush(stdin);不管什么情况都可行。
函数名: fflush 

功 能: 清除一个流 

用 法: int fflush(FILE *stream);
#include <stdio.h> 

int main() 



    int a; 

    char c;
    do 

    { 

        scanf("%d",&a); 

        fflush(stdin); 

        scanf("%c",&c); 

        fflush(stdin); 

        printf("a=%d     c=%c/n",a,c);
    }while(c!='N'); 

}     
这里再给一个用“空格符”来处理缓冲区残余信息的示例:
运行出错的程序:
#include <stdio.h> 

int main() 



    int i; 

    char j; 

    for(i = 0;i < 10;i++) 

    { 

        scanf("%c",&j);/*这里%前没有空格*/ 

    } 

}
使用了空格控制符后:
#include <stdio.h> 

int main() 



    int i; 

    char j; 

    for(i = 0;i < 10;i++) 

    { 

        scanf(" %c",&j);/*注意这里%前有个空格*/ 

    } 

}
    可以运行看看两个程序有什么不同。
问题四   如何处理scanf()函数误输入造成程序死锁或出错?
#include <stdio.h> 

int main() 



int a,b,c; /*计算a+b*/
scanf("%d,%d",&a,&b); 

c=a+b; 

printf("%d+%d=%d",a,b,c); 

}
如上程序,如果正确输入a,b的值,那么没什么问题,但是,你不能保证使用者每一次都能正确输入,一旦输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果,呵呵,这可能所有人都遇到过的问题吧?
解决方法:scanf()函数执行成功时的返回值是成功读取的变量数,也就是说,你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,它就返回几。但这里还要注意另一个问题,如果输入了非法数据,键盘缓冲区就可能还个有残余信息问题。
正确的例程:
#include <stdio.h> 

int main() 



int a,b,c; /*计算a+b*/

while(scanf("%d,%d",&a,&b)!=2)fflush(stdin);

c=a+b;

printf("%d+%d=%d",a,b,c);

}

#include<stdio.h>
void main(){
int a;
char b;
printf("input a integer\n");
scanf("%d",&a);
//这里需要吸收 回车符 下面有种方法,第二种我没看懂 谁能改下代码 告诉我第二种怎么用
printf("input a char\n");
scanf("%c",&b);
printf("%d,%c\n",a,b); }
/*
(1)用getchar()清除
(2)用"%1s"来限制
(3)用格式串中空格或"%*c"来"吃掉"
(4)用函数fflush(stdin)清除全部剩余内容
*/
#include<stdio.h>
int main(){ int a;
char b; printf("input a integer\n");
scanf("%d",&a);
//这里需要吸收 回车符 下面有种方法,第二种我没看懂 谁能改下代码 告诉我第二种怎么用
printf("input a char\n");
scanf("%1s",&b); printf("%d %c\n",a,b);
system("pause");
return 0; }

环境(dev c++)

测试结果

可以看出a的值异常了,为什么呢?

这应该和编译器有关系,因为%1s的输入方式的问题。

解决方法有两种:

第一:

  1. char b;
  2. int a;

将这两个变量的声明换一下,哈哈,以前老师说过。但我感觉着不是解决方法,如果还有其他的变量,这种方式是不是还会危害其他呢。

第二:

  1. #include<stdio.h>
  2. int main(){
  3. int a;
  4. char b[2];
  5. printf("input a integer\n");
  6. scanf("%d",&a);
  7. //这里需要吸收 回车符  下面有种方法,第二种我没看懂 谁能改下代码 告诉我第二种怎么用
  8. printf("input a char\n");
  9. scanf("%1s",&b);
  10. printf("%d %c\n",a,b[0]);
  11. system("pause");
  12. return 0;
  13. }

b声明成字符创的形式,哈哈,这个好。。。。

结果为:

c语言scanf()停止接受输入及scanf("%c",&c)吃掉回车或者空格字符的问题的更多相关文章

  1. 正确显示textarea中输入的回车和空格

    在textarea中输入的文本.如果含有回车或空格.在界面上显示的时候则不那么正常.回车消失了,空格变短了. 如何解决这个问题呢.有2种方法. 1.使用<pre>标签 w3c对pre元素是 ...

  2. C语言中最常用的三种输入输出函数scanf()、printf()、getchar()和putchar()

    本文给大家介绍C语言中最常用的三种输入输出函数scanf().printf().getchar()和putchar(). 一.scanf()函数格式化输入函数scanf()的功能是从键盘上输入数据,该 ...

  3. C语言输入语句scanf与fgets linux下

    1.测试使用scanf的一个例子: #include "stdio.h" #include "string.h" int main() { char name[ ...

  4. scanf()中清除输入缓冲区的几种方法归纳

    应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种 ...

  5. c++之 scanf 接收用户输入内容

    该代码全部在Visual Studio 2015中编写,有关VS2015的安装后期在写相关的博客 scanf 介绍 在程序开发中,有时候需要通过获取用户输入的数据,进行对应的操作,scanf就是用来接 ...

  6. C语言初步学习I/O函数scanf、getchar、printf和putchar

    scanf().printf().getchar()和putchar()这四个函数能够让用户和程序交流,所以被称为输入/输出函数,或简称为I/O函数. 这里先结合缓冲输入来讲讲scanf()和getc ...

  7. 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出

    [源码下载] 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 预处理命令 输入 ...

  8. C++学习(七)(C语言部分)之 输入

    输入学习时的笔记(其实也没什么用,留着给自己看的) 输出是指 把内容打印到控制台窗口 输入是指 把内容输入到程序里 scanfscanf 从键盘获取内容到程序里格式占位符+变量要加取地址符 1.格式占 ...

  9. 编写一个C语言函数,要求输入一个url,输出该url是首页、目录页或者其他url

    编写一个C语言函数,要求输入一个url,输出该url是首页.目录页或者其他url 首页.目录页或者其他url 如下形式叫做首页: militia.info/ www.apcnc.com.cn/ htt ...

随机推荐

  1. Electron 开发环境下总是 crash

    全局安装一个 electron devtool 关掉 崩溃时选择重新打开

  2. docker 错误排查:无法进入容器.

    docker 错误排查:无法进入容器. #docker exec -it 3c1d bash rpc error: code = 2 desc = oci runtime error: exec fa ...

  3. samba和SELINUX 冲突

    在使用Samba进行建立Window与Linux共享时,要是不能访问,出现“您可能没有权限使用网络资源”. setsebool -P samba_enable_home_dirs on setsebo ...

  4. java基础31 List集合下的Vector集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...

  5. No.12 selenium for python 截屏

    一.selenium for python 提供的几种截图方法 从上至下,很容易理解 1.as_file 获取当前window的截图,参数filename则表示截图的路径以及名称 出现IOError时 ...

  6. git —— 分支

    git中每一个分支相当于一个时间线 并列且相互平行 控制用指针控制~ 1.第一种创建命令: $ git branch 分支名称 —— 创建分支 $ git checkout 分支名称 —— 切换分支 ...

  7. Java 从多层嵌套中访问内部类的成员

    一个内部类被嵌套多少层并不重要--它能透明地访问所有它能嵌入的外围类的所有成员 //: innerclasses/MultiNestingAccess.java // Nested classes c ...

  8. python包/模块路径

    当Python执行import语句时,它会在一些路径中搜索Python模块和扩展模块.可以通过sys.path查看这些路径,比如: >>> import sys >>&g ...

  9. MySQL学习笔记:生成时间维度表2

    实现目的: 测试: # 测试 加一秒 SECOND), INTERVAL SECOND); SECOND),'%H%i%s');# 第一秒 SECOND),'%H%i%s');# 最后一秒 SELEC ...

  10. Windbg在应用层调试漏洞时的应用

    主要记录一些在应用层调试漏洞的技巧,不会写一些基本的命令,只记录比较有用的平时难以想到的调试方法. 1.!address eax 查看对应内存页的属性,如果poc触发异常之后就可以用这个指令看一下触发 ...