你真的会用scanf吗?

你真的会用scanf吗?

  1. scanf使用技巧1
4 5 6 7 8 9 4 5 4

如何将以上数字输入数组呢,只需要用下面这段代码

scanf("%d",&arr[i]);

实际上在键盘上输入时,键入4<空格>5<空格>6<空格>…

  1. scanf使用技巧2
    当我们有有一个很大的数组需要输入时,而每次输入元素的个数都不一样,这时该怎么办呢?
    使用下面这段代码即可
int arr[100],i=0;
do
{
   scanf("%d",&arr[i]);
   i++;/*i即可代表当前实际输入数组的元素的个数*/
 }while(getchar()!='\n');

接下来真正的干货来啦!!!
3. scanf和getchar进行读入字符时的区别(注意是读入字符)
相信小伙伴都知道,scanf(), getchar()都是标准输入函数,在程序的读写中使用非常频繁,但很多人都认为其非常简单,进而造成一些虽小而致命的错误
程序1

int main()  
{  
       char ch1, ch2;  
       scanf("%c", &ch1);   
       scanf("%c", &ch2);  
       printf("%d  %d\n", ch1, ch2);  
       return 0;  
}  

程序2

int main()  
{  
       char ch1, ch2;  
       ch1 = getchar();  
       ch2 = getchar();  
       printf("%d  %d\n", ch1, ch2);  
       return 0;  
}  

该程序的功能很简单:就是从键盘读入两个字符,然后打印出这两个字符的ASCII码值。
实际操作情况:,当从键盘输入一个字符A后,就打印出了 结果,同时程序结束运行;打印结果为”65 10“。
其实,有点经验的小伙伴可以看出,10为空格的ASCII码,这究竟是为什么呢?
分析
首先,我们看一下输入操作的原理, 程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而scanf函数直接从输入缓冲区中 取数据(注意此时仅是在读入数据是字符的情况下,读入字符串不样)。正因为scanf函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,scanf函数会直接取得这些残留数据而不会请求键盘输入,这就是例子 中为什么会出现输入语句失效的原因!
其实这里的10恰好是回车符!这是因为scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。而读 取时遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符\n,这样第二次的读入函数直接从缓冲区中 把\n取走了,显然读取成功了,所以不会再从终端读取!这就是为什么这个程序只执行了一次输入操作就结束的原因!

4.scanf和gets读取字符串时的区别(注意是字符串)

程序3

int main()  
{  
       char str1[20], str2[20];  
       scanf("%s",str1);   
       printf("%s\n",str1);      
       scanf("%s",str2);    
       printf("%s\n",str2);    
       return 0;  
}  

程序的功能:读入一个字符串输出,在读入一个字符串输出。可我们会发现输入的字符串中不能出现空格,例如:
测试输入1:
Hello world!
输出:
Hello
world!
分析
到此程序执行完毕,不会执行第二次的读取操作!这个问题的原因跟问题一类似,第一次输入Hello world!后,字符串Hello world!都会被读到输入缓冲区中,而scanf()函数取数据是遇到回车、空格、TAB就会停止,也就是第一个scanf()会取出"Hello", 而"world!"还在缓冲区中,这样第二个scanf会直接取出这些数据,而不会等待从终端输入。
测试输入2:
Hello[Enter]
Hello[输出]
world[Enter]
world[输出]
分析
程序执行了两次从键盘读入字符串,说明第一次输入结束时的回车符被丢弃!即:scanf()读取字符串会舍弃最后的回车符!

我们再看一下gets()读取字符串的情况:
用scanf来读取一个字符串时,字符串中是不可以出现空格的,一旦出现空格,后面的数据就会舍弃残留在缓冲区中。其实有另外一个函数是可以接受空格的,那就是gets(),下面我们看一下这个函数的应用,我们把程序3改动一下:

int main()  
{  
       char str1[20], str2[20];  
       gets(str1);   
       printf("%s\n",str1);      
       gets(str2);    
       printf("%s\n",str2);    
       return 0;  
}  

分析
显然与上一个程序的执行情况不同,这次程序执行了两次从键盘的读入,而且第一个字符串取了Hello world! 接受了空格符,而没有像上一个程序那样分成了两个字符串!所以如果要读入一个带空格符的字符串时因该用gets(), 而不宜用scanf()!

总结以下

  1. scanf在输入字符和字符串时情况不同
  2. 读取字符
    scanf()以Space、Enter、Tab结束一次输入,不会舍弃最后的回车符(即回车符会残留在缓冲区中);
    getchar()以Enter结束输入,也不会舍弃最后的回车符;
  3. 读取字符串
    scanf()以Space、Enter、Tab结束一次输入
    gets()以Enter结束输入(空格不结束),接受空格,会舍弃最后的回车符!
  4. 为了避免出现上述问题,必须要清空缓冲区的残留数据,可以用以下的方法解决:
    C语言里提供了函数清空缓冲区:函数是fflush(stdin);
    或者采用一次输入后接while(getchar()!='\n'){}来清空缓存区
    5.转自大佬博客 https://blog.csdn.net/zqixiao_09/article/details/50189477
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值