精华内容
下载资源
问答
  • scanf()函数有返回值,且返回值是正确读取的个数 scanf("%d%d", &x, &y); 若是x,y都被正确读取了,则返回值是2; 若只有x被正确读取了,则返回值是1;(不存在x没有被正确读取,但是y被正确读取的情况) 若...
    1. scanf()函数有返回值,且返回值是正确读取的个数
      scanf("%d%d", &x, &y);

      • 若是x,y都被正确读取了,则返回值是2;
      • 若只有x被正确读取了,则返回值是1;(不存在x没有被正确读取,但是y被正确读取的情况)
      • 若x,y都没有被读取,则返回值为0;
      • 若是遇到错误或者文件末尾,则返回-1,这个-1就是常见的E0F(end of file),他俩等价;
    2. scanf是从缓存区读取数据的

      • 每成功读取就会把缓存区的该数据删掉;
      • 若是需要读取但是缓存区还没有值,scanf就会一直等待用户输入(阻塞)直到用户输入;
      • 若是读到不是scanf需要的值,scanf不会清空缓存,会继续接着读,除非缓存里面是scanf需要的值。
    3. scanf对不同类型输入的处理方式
      前提:空格、回车、制表符Table都是空白字符;

      • 对于%d类型的输入,scanf默认的分割符是所有的空白字符。也就是说如果一个scanf函数中出现scanf("%d%d",&a,&b),那么用任何一个空白字符来分隔两个整数a,b的值,变量a,b都可以接收到正确的输入。且scanf会忽略输入数据项前面的空白字符。

      • 对于%c类型的输入,scanf默认所有字符都是需要接收的字符,包括所有的空白字符也会被接收。也就是说如果一个scanf函数中出现scanf("%c%c",&a,&b),那么输入c t,最后a是c,b是,t是接收不了的;

      • 对于%s类型的输入,scanf默认的分割符是所有的空白字符。scanf对于字符串输入的处理和对整数类似,会忽略前导的空白字符,而且默认的分隔符是所有的空白字符。
        - 这里需要详细讲一下
        - 比如scanf("%[^\n]",s);这句代码的意思是除了回车键,其余都接收放进s字符串里面。如果你打了回车,回车不会被接收进字符串s里面,回车之前的所有字符包括空格都会被放进字符串s里面。
        - 那么,这个回车呢?它会一直被留在缓存里面,只要不动这个缓存,他会一直在。此时scanf的返回值是1(如输入:abc\n)或者0(如输入:\n)
        - 上面的代码不会有任何问题,但是一旦写了写了下面的代码,就会出错。

        	while(scanf("%[^\n]", s) != EOF){
        		printf("%s", s);
        	}
        

      原因是:scanf("%[^\n]", s)接收非回车符,一旦碰到回车就停止,然后进入循环里面执行。但是缓冲区里面的\n一直在,没有被读取之后删除,scanf("%[^\n]", s)的返回值一直是0或者1,while循环里面一直成立,scanf一直在尝试读取非回车符,但是一直遇到缓存里面的回车符,每遇到一次刚刚的回车符就printf("%s", s)以下之前输入的值,就会出现无限循环输出…

    4. 缓冲区数据的读取
      像第3点那样,出现回车一直呆在缓冲区消不掉怎么办?

      • 第一种方法:使用fflush(stdin);主动清空缓冲区
        	while(scanf("%[^\n]", s) != EOF){
        		fflush(stdin);
        		printf("%s", s);
        	}
        
      • 第二种方法:使用getchar()函数,主动吞掉缓冲区的第一个字符,也就是卡住的那个回车字符
        	while(scanf("%[^\n]", s) != EOF){
        		getchar();
        		printf("%s", s);
        	}
        
      • 第三种方法:不使用scanf("%[^\n]", s)使用gets()函数,gets()函数会把回车和EOF当成分隔符,但是不具备对缓冲区的一些操作,所以用来处理字符串好,但是改成其他的分隔符就不太好用了,但是不具有通用性。

    可以用以下代码做测试。

    附录1:

    #include<stdio.h>
    
    int main(){
    	char s[100];
    
    	while(scanf("%[^\n]", s) != EOF){
    		//fflush(stdin);
    		//getchar();
    		printf("%s", s);
    	}
    
    	return 0;
    } 
    

    附录2:
    可以参考这位博主的博客理解。https://blog.csdn.net/xia7139/article/details/14522493

    展开全文
  • C语言scanf语句吃掉回车或者空格问题详解

    万次阅读 多人点赞 2019-10-18 14:41:07
    我们经常在C语言输入的时候,会发现scanf空格或者回车“吃掉”了,导致程序的运行结果与预期不一致,以下面一个简单例子为例 #include<stdio.h> char str[10]; int main() { int i; for(i=0;i&...

    问题描述:

    我们经常在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

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

    在这里插入图片描述
    在对应位置加好空格就可以了,

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

    展开全文
  • 一、什么是scanf语句? 它是格式输入函数,即按用户...可以读取对应类型的数值并且存储到指定的变量,并且可以读取多个数值,如数字,字符,字符串等,每次用到scanf‘时,都会从数据缓存区读取一个多个字符,并存.

    一、什么是scanf语句?

    它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。与printf函数一样,都被声明在头文件stdio.h里,因此在使用scanf函数时要加上#include <stdio.h>

    读取方式:

    一般格式为:scanf(格式控制,地址列表),也就是scanf("%?",&?);

    可以读取对应类型的数值并且存储到指定的变量,并且可以读取多个数值,如数字,字符,字符串等 ,每次用到scanf时,都会从数据缓存区读取一个或多个字符,并存入相对应的变量中。

    【注意】

    • scanf()在读取数值时会跳过空格、制表符以及换行符。
    • %c只能输出或输入一个字符,%s输出的是一串字符。
    • scanf中空格的作用:

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

    二、scanf()常见吃掉回车或空格问题

    我们经常在练习的时候会发现scanf把回车或者空格“吃掉了”,这导致我们的运行结果和预期的不同,大家看下面这个例子(例1):

    #include <stdio.h>
    
    int main()
    {
    	char arr[100];
    	scanf("%s", arr);
    	printf("%s\n", arr);
    	return 0;
    }

    在这里我们输入abcdef,结果如下:

    但当输入的数值当中有空格时:

     从这里我们可以看到,遇到空格scanf就停止输入了,因为scanf已经读取了字符串"abc",之后遇到空格,就会结束一次输入,空格不会被接收,遇到空格就认为对arr的赋值结束了,后面的def被忽略,这里我们要注意的是:def会留存在键盘缓存区。

    接下来看另外一个例子(例2):

    #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");之间有一个空格,我们输入a的值之后,输入空格(此时空格被看做字符对待,空格会读取停止字符并释放掉),再输入b的值,第一次输入正常,这时scanf把第一次输入时的回车符也当做字符取对待了,当我们输入完b之后按回车,这个回车是放在缓冲区的;第二次调用scanf("%c%c",&c1,&c2);时,把还在缓冲区的回车当做字符赋值给c1,之后把a赋值给c2。所以第二次输入有问题了。

    三、解决方法

    1、当scanf()函数在接收字符串时,遇到空格就会停止接收,我们可以使用gets()函数代替,或者使用一个参数,%[ ]

    %[ ]:这个参数的意义是读入一个字符集合。[ ]是个集合的标志,因此%[ ]特指读入此集合所限定的那些字符。比如%[A-Z]是输入大写字母,一旦遇到不在此集合的字符便停止。如果集合的第一个字符是“^”,这说明读取不在“^“后面集合的字符,即遇到”^“后面集合的字符便停止,此时读入的字符串是可以含有空格的。(\n 表示换行符)

    则上面例1的正确代码为:

    #include <stdio.h>
    
    int main()
    {
    	char arr[100];
    	scanf("%[^\n]", arr);
    	printf("%s\n", arr);
    	return 0;
    }

    结果为:

    2、当scanf()函数在接受多个单个字符时,只需要在输入的对应位置加好空格即可(把缓冲区里的内容赋值给相对位置)。

    则上面例2的正确代码为:

    #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;
    }

    结果为:

     【如有错误欢迎评论指正!】

    展开全文
  • 由于对字符解析方式及字符特点不同(如数字中一般不会出现空格回车等特殊字符)不同,%d格式一般不会在连续输入时,遇到问题。而%s和%c却会出现各种各样的问题,比如回车问题,空格问题等。 我们已经习惯了上面的代码...

    scanf和回车的关系:

    先看一个我们经常使用的代码:
      
      char c;
      scanf("%c", &c);
      scanf 的各种格式中,%d、%c、%s三种最常用,通常都是以回车作为一次输入的结束。由于对字符解析方式及字符特点不同(如数字中一般不会出现空格回车等特殊字符)不同,%d格式一般不会在连续输入时,遇到问题。而%s和%c却会出现各种各样的问题,比如回车问题,空格问题等。

    我们已经习惯了上面的代码,再看下面存在连续输入时的情况:
      int i;
      char c;
      scanf("%d", &i);
      scanf("%c", &c);
      如果我们为i赋值为3,并以回车的方式结束对i的赋值。再按常规思路为c赋值时,就会发现并不能为c赋值,并且c自动赋值为十进制的10,也就是回车键。why???

    要回答这个问题,先看scanf函数的功能和工作原理:

    scanf函数这个函数的作用是从标准输入设备获取输入值,并存储到参数列表中指针所指向的内存单元,如果读入成功,函数会返回读入成功的数据的个数;scanf函数的结束通常有3种,遇到空格、回车或者tab键为常用的结束方式;或者按照格式控制符的指定来控制结束,如%5d类的格式;遇到非法输入也会自动结束。

    对常用的三种格式,结束符号分别如下:

    %d格式输入,默认分隔符是所有的 white-spaces(空格、回车、制表);

    %c格式输入,则按ASCII字符考虑,无分隔符。可能会受到之前输入的影响,必要时用fflush(stdin);清除缓冲区;

    %s 是 字符串格式,默认分隔符是所有的 white-spaces,输入后自动加入结束符"\0"。

    继续上面的由于连续输入带来的问题,往深了说,就涉及到缓冲区了。scanf函数是以删除的方式从缓冲区读取数据(缓冲区中存储来自标准输入的数据)。如果缓冲区是空的,就阻塞之,等待从键盘输入;并且scanf还能对数字输入忽略先导的空白符,如\n\t和空格等(注意,对字符输入并不忽略先导字符,这个也是很自然的道理,因为\n\t和空格在字符中都是合法的字符)。

    scanf的缓冲机制和对字符的处理方式就造成了scanf对字符%c和字符串%s的读取时的各种意外。比如上面的例子,回头分析这段代码:

    输入了i的值为3然后按回车,当前缓冲区中数据为”3\n”,由回车的作用scanf开始从缓冲区中读取一个%d控制的数据,也就是3,此时缓冲区中还剩”\n”;对下一个scanf函数的格式控制是%c,这个情况下并不忽略先导的空白字符\n,而是直接赋给字符c了。想要查看缓冲区的内容,stdin[s1] ,如果想要查看当前stdin中的内容,一般方法都比较忤逆,可以尝试使用文件操作freopen将stdin中的数据重定向到另外一个file*中。这个另辟一文。

    如何解决这个缓冲区和字符解析的问题呢?既然缓冲区有我们不需要的东西,那就清除缓冲区。微软系统中是fflush(stdin)函数可以清除缓冲区,而有的编译系统并没有定义对stdin的fflush操作,就把stdin中的数据读出来:

    1. 可以使用fgets()函数,这个函数没有编译器的限制;

    2. 或者把缓冲区中多余的东西交给别的函数,如getchar(),具体代码为 while( (c = getchar() ) != ‘/n’ && c != EOF );

    3. 上面的方法基于原理,但有点麻烦,尤其是遇到字符%c和字符串%s对回车的处理时。C还提供了gets()函数解决了这个问题,gets()函数是不论中间有什么字符,一律读进来,直到遇到回车符;

    4. C++中,还可以操作stdin的指针,stdin是一个File*类型的数据结构,使stdin->_IO_read_ptr = stdin->_IO_read_end;。但是C中不可以。

    scanf和空格键

    前面就有说,scanf函数,根据格式的不同,对空白字符的处理也不同。%d格式下,对空白字符不敏感,通常都是作为结束符的;对%c来说,对回车符比较敏感,空格的做为一个普通字符处理的;对%s来说,回车和空格都是当前函数的结束字符,由于缓冲区stdin机制,这里又要特别注意 空格和回车对%s的影响。

    %s默认分隔符是所有的 white-spaces,输入后自动加入结束符"\0",使其成为一个字符串(之所以加上\0,是和字符数组char[]的结束符有关的,C中是没有string这个类型的,是使用char[]结构实现字符串)。值得注意的是,即使输入字符的长度足够,%s是宁愿舍弃输入字符,也要把/0加上去的,作为字符串的结束。并且,scanf会忽略缓冲区开头的空格,知道遇到一个非空格字符,才开始向内存中读取数据。

    比如,我们想要输入”The C Programming Language.\n”,中间的空格怎么处理呢?

    其中一个解决方法是使用gets函数,这个函数是以回车符作为输入结束的标志的;还有一种解决方式是:scanf("%[^\n]", c):

    char c[15];
      scanf("%[^\n]", c[s2] );
      只是scanf("%[^\n]", c);和gets这两种处理方式都是不忽略所有的空格,包括缓冲区开头的空格;这一点和scanf("%s",c);的处理方式不同,%s的方式,忽略缓冲区开头的空格。

    另:scanf的返回值

    scanf()函数返回的值为:正确按指定格式输入变量的个数;也即能正确接收到值的变量个数。在类型匹配错误的时候,以非正常的方式退出。可以利用scanf函数的返回值判断输入是否正确,并进行流程控制:

     int i = 0;
     char c1[15];
     while((scanf("%c", &c1[i])!=EOF) && i<14)
     {
              i++;
     }
    

    [s1]stdin是标准输入,一般针对键盘,是个FILE* 类型的数据。

    [s2]这里注意使用c 还是 &c:

          c是个数组,数组 即代表了数组的首地址,所以可以使用c;
    
          &c,表示数组c的地址,也就是指首地址,所以也是可以的。但通常c更符合逻辑一点。这在读取%s类型的数据时可以说明这一点:
    
                  scanf(“%s”, c);
    
    展开全文
  • c语言scanf用法

    万次阅读 多人点赞 2019-07-10 23:47:01
    C语言scanf的用法和注意事项 内容参考:https://blog.csdn.net/hk_kang/article/details/78747726 scanf概念 scanf是格式输入函数,功能是在屏幕上输入指定的信息。简单的来说和printf相似却不相同。 scanf调用...
  • 在编写把**%c 输入 2 个数字(0–9),将 2 个数字组成 2 位数并每位上的数字不能相同,以%d 输出**题目时,碰到输入字符把空格回车也输入的问题,多方查找后终于解决 以下是我碰到的问题展示 代码: #include <...
  • C语言scanf函数输入回车符的问题

    千次阅读 多人点赞 2019-08-02 11:28:58
    作者:gadflycq时间:2009-04-12 在用c语言编写输入语句的时候常用到scanf函数,初学者在刚用scanf函数输入时,...scanf("%c%c%c"),那么输入的时候就必须连续输入3个字符,中间不能有任何空格逗号或者回车符等...
  • 测试源码: #include<...//这个gets会吸收scanf留下的回车,并提前结束,即a字符串为空 printf("%s\n",a); gets(b); printf("%s\n",b); return 0; } 输入 100回车qwer 结果: 输入:100空格
  • c语言scanf函数与空格回车

    千次阅读 2017-08-02 16:51:39
    1、scanf的返回值 scanf通常返回的是成功赋值(从标准输入设备赋值到参数列表所指定的... F6;在UNIX系统上,用CTRL+D。),则返回EOF,比如: scanf("%d%d", &x, &y); scanf函数仅在每一个数据域均有数据,并
  • C语言scanf函数与空格

    万次阅读 2010-12-14 20:52:00
    | 问题描述一:(scanf()读入字符串中的空格) | ---------------------------------------------------- #include<stdio.h><br />int main() {  char a[777];  scanf("%[^/n]",&...
  • scanf("%c%c",&a,&b)"; 如果输入:a b 那么a=a,b=空格 所以如果输入形式为:a b 这种一个一个字符输入并且字符之间用空格隔开的时候要用 scanf("%c %c",&a,&b)"; 这种输入之中就有空格的形式 ...
  • c语言scanf函数

    千次阅读 多人点赞 2018-11-28 12:09:46
    定义:scanf函数称为格式输入函数,即按用户指定的格式从键盘上把数据输入到变量中。 格式:scanf(“格式控制字符串”,地址表列); 例如:scanf(“%d”,&amp;amp;amp;amp;a); &amp;amp;amp;amp;是一...
  • scanf的语法格式 scanf(格式控制(参数表列),地址表列) 地址表列,由若干个地址组成的表列可以为变量地址...scanf()会进行一个“吃空白”的操作,也就是把空格回车、制表符全都吃掉 scanf()默认把空白作为分割多个输
  • 要输入带空格的字符串,要用到一个格式字符:%[] --> 一个字符集。 “%[]”的作用是扫描字符集合: 例如:scanf(“%[^\n]”,str); 具体作用是:如果输入的字符属于方括号内字符串中某个字符,那么就提取该字符...
  • C语言scanf函数详解和示例

    千次阅读 2020-04-11 16:04:56
    一、数据输入 编写程序的主要目的就是为了处理数据。数据从哪里来?数据的来源有很多种方式,如从磁盘文件中读取数据、从数据库中读取数据、从网页...scanf:格式化输入函数,一次可以输入多个数据,保存到多个变量...
  • #include &lt;stdio.h&gt; int main() ... scanf("%c",(p+i)); } for(i=6;i&lt;10;i++) *(p+i)='#'; for(i=0;i&lt;10;i++) printf("%c",p[i]); retur...
  • 问题:C语言中用scanf函数输入字符、数字、字母和字符串时,如果带有回车符会出现什么情况呢? 出现问题情境: notepad++ 7.5.9.0 gcc version 4.7.1 strcmp函数的应用 #include&lt;stdio.h&gt; int ...
  • scanf()函数的原理 想象输入设备(键盘)连接着一个叫“缓冲”的东西,把缓冲认为是一个字符数组。 当你的程序执行到scanf时...的时候,由于scanf是读数据直到看见空白符(空白符:指空格符、制表符、回车符)就停止...
  • 目录目的解决scanf()跳过空白、fgets()...所以创建了一个s_gets()函数,可以读取空格分隔的一行字符 char * s_gets(char * st, int n) { char * ret_val; char * find; ret_val = fgets(st, n, stdin); if (ret_
  • main() { ...输入一个数字再按空格会继续读入数字,如果输入的数据不足10个,怎么让它在输入完毕后按回车自动跳出循环? ---- #include #include int main() { int i,a[10]; char c; for(i=0
  • C语言scanf匹配用法

    千次阅读 2018-12-26 12:41:52
    不同系统的换行符制定 不同系统之间传递文本文件 函数scanf参数列表及返回值 输入缓冲区清除剩余字符 指定字符串的输入长度 输入支持含空格的字符串 灵活指定输入长度和格式
  • C语言scanf函数中空格的用处

    千次阅读 2019-02-14 21:55:58
    可能用多了C++语言吧,现在居然都不熟悉scanf空格还有这么多意义,惭愧惭愧,也一直对字符和字符串的输入方式比较混淆 代码如下:如不会有回车问题的困扰,也不用加getchar().是由于scanf中的空格可以匹配的是一切...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,494
精华内容 4,197
关键字:

c语言scanf空格或回车

c语言 订阅