C 【printf 和 scanf 函数的使用】

        对于printf函数,我们主要要掌握printf函数的输出格式

        而对于scanf函数,我们则要知道几个输入过程中的错误输入情况和scanf函数的实现原理

  •  (1)printf 函数
  •     printf格式控制 部分 的完整格式:
  •     "% - 0 m.n l或h 格式字符"
  •     
  •     下面对组成格式说明的各项加以说明: 
  •                ① %   表示格式说明的起始符号,不可缺少。
  •                ② -   有-表示左对齐输出(右侧补空格),如省略表示右对齐输出(左侧补空格)。
  •                ③ 0   有0表示指定空位填0,如省略表示指定空位不填。
  •                ④ m.n   m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度。用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。
  •                ⑤ l或h   l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型。
  •                ⑥ 格式字符(格式字符用于 指定输出项的 数据类型输出格式) :
  •                                 d格式:用来输出十进制整数。有以下几种用法:
  •                                           %d %hd %ld
  •                                 o格式:以无符号八进制形式输出整数
  •                                 x格式:以无符号十六进制形式输出整数
  •                                 u格式:以无符号十进制形式输出整数
  •                                 c格式:输出一个字符
  •                                 s格式:用来输出一个串。有几种用法列举:
  •                                              ① %s   例如:printf("%s","CHINA")输出"CHINA"字符串(不包括双引号)。
  •                                              ② %ms   输出的字符串占m列,如字符串本身长度大于m,则突破获m的限制,将字符串全部输出。若串 长小于m,则左补空格。
  •                                              ③ %-ms   如果串长小于m,则在m列范围内,字符串向左靠,右补空格。
  •                                            (以下④⑤条中的 m和n 的含义不同于上面)
  •                                              ④ %m.ns   输出占m列,但只取字符串中 左端 n个字符。这n个字符输出在m列的右侧,左补空格。 注意:如果n未指定,默认为0。如果n>m,则m自   动取n的值,即保证n个字符正常输出。
  •                                              ⑤ %-m.ns   其中m、n含义同上,n个字符输出在m列范围的左侧,右补空格。 注意:如果n未指定,默认为0。如果n>m,则m自动取n的值,即保证n个字符正常输出。


  •  (2)scanf 函数
  •     scanf是一个阻碍式函数,程序在执行过程中会停在scanf函数出现的地方,直到接收数据时才会执行后面的代码。

  •     scanf使用时注意的几个点:
  •                  ① 如果在控制台输入时输入了多个空格、回车、Tab都会被系统忽略的(这其中包括输入多个实型常量 和型常量时如果间输入了多余的空格、回车、Tab也是都会被系统忽略的
  •                  ② 字符型常量整型常量 或 实型常量 混合输入的时候,要注意添加分隔符,来避免无意输入 空格 造成的错误
  •                  ③ 在scanf中,尽量不要使用\n,因为会造成在输入的时候无限换行。如果使用了\n,那么在输入的时候一定要原样输入“\n”才可以解决
  •    
  •     scanf实现原理:系统会将用户在控制台输入的内容放入输入缓冲区,scanf会从输入缓冲区内逐个取出内容赋值给格式符,如果类型不一致的话不会修改原有数据。并且如果输入缓冲区中不为空,那么再次使用scanf时scanf会一直从缓冲区中获取值,而不会要求用户再次输入。
  •  
  •     接下来一段代码会将上面 需要注意的几个点 和 实现原理 相结合为大家展示
  •    
    #include <stdio.h>
    
    int main(int argc, const char * argv[]) {
        
        int intValue1 = 1;
        char charValue1 = '1';
        int intValue2 = 2;
        
        char charValue2 = '2';
        int intValue3 = 3;
        
        printf("-----第一次输入:-----\n");
        scanf("%d%c%d", &intValue1, &charValue1, &intValue2);
        printf("\n-----第一次输出:-----\n");
        printf("intValue1 = %d,charValue1 = %c,intValue2 = %d\n", intValue1, charValue1, intValue2);
        
        printf("\n-----第二次输入:-----\n");
        scanf("%c%d", &charValue2, &intValue3);
        printf("\n-----第二次输出:-----\n");
        printf("charValue2 = %c,intValue3 = %d\n\n", charValue2, intValue3);
        
        return 0;
    }
    
    /*
     *  运行结果:
     
        -----第一次输入:-----
        19 s 32
    
        -----第一次输出:-----
        intValue1 = 19,charValue1 =  ,intValue2 = 2
    
        -----第二次输入:-----
    
        -----第二次输出:-----
        charValue2 = s,intValue3 = 32
     
     */
    

  •    运行结果分析:
       
       首先看输入部分,第一次看似输入了3个值,实则不然,我们输入了5个。分别是:19 空格 s 空格 32
       再看第二次输入,直接被跳过了。
     
       其次看输出部分,一次输入(只按了一次回车),两次结果都打印出来了:
       intValue1 = 19,charValue1 =  ,intValue2 = 2,charValue2 = s,intValue3 = 32

       经上面的分析,我们一共在控制台手动输入了5个值,也就是让scanf去输入缓冲区去取5次值,第一次输入scanf将前三个值取出来,也就是取出 19、空格、s,并将他们赋给intValue1、charValue1、intValue2,前两个正常赋值,但是第三个值 s 和 intValue2的类型不匹配,所以输入缓存区里的值 s 并没有被取走,而intValue2显示的就是它初始化时被赋予的值 2。
       试想一下,现在输入缓存区中还存在三个值,那就是第一次没被取走的 s 以及 空格 和 32。所以说第二次控制台输入不会执行,而是继续在输入缓存区中取值。自然 s 赋给了 charValue2,又因为 空格 换行 tab 遇到 非char类型的值时会被忽略,所以说 空格 就被忽略了。那么最后一个值 32 就被赋给intValue3了。
     
     
  •    接下来一个小问题,来加深理解这部分内容:
  •   
    #include <stdio.h>
    
    void test1();
    
    int main(int argc, const char * argv[]) {
        
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        int e = 0;
        int f = 0;
    
        printf("第一次输入:\n");
        scanf("%i,%i,%i", &a, &b, &c);
        printf("-----第一次输入结束-----\n");
        printf("第一次输出结果---%i,%i,%i,%i,%i,%i\n", a, b, c, d, e, f);
    
    //    setbuf(stdin, NULL); // 清空输入缓存区的缓存数据
    
        printf("第二次输入:\n");
        scanf("%i,%i,%i", &d, &e, &f);
        printf("-----第二次输入结束-----\n");
        printf("第二次输出结果---%i,%i,%i,%i,%i,%i\n", a, b, c, d, e, f);
        
        
        return 0;
    }
    
    /*
     *  运行结果:
     
        第一次输入:
        1,2,3,4,5,6
        -----第一次输入结束-----
        第一次输出结果---1,2,3,0,0,0
        第二次输入:
        -----第二次输入结束-----
        第二次输出结果---1,2,3,0,0,0
     
     */
  •    运行结果分析:

               和上面的程序一样,一次性输入多个值,那么会在缓存区里存储未赋值的数据。那为什么第二次输入的时候d、e、f的值还是0呢?不应该是4,5,6吗?这是因为在输入的时候我们加上了逗号作为分隔符,而一次输入6个值时,c与d之间是没有逗号作为分隔符的,但我们却多输入了一个逗号,那么逗号就会从缓存区中取出并依次赋给d、e、f,但类型不匹配,所以说赋值失败,于是输出结果d、e、f还是0。


  •   
    /*
     *  如果是按下面的方式进行输出,空格去替代3和4之间的逗号,那么赋值时空格遇到非char类型的数据自动忽略,所以后面的4、5、6成功赋值
     *  运行结果:
     
        第一次输入:
        1,2,3 4,5,6
        -----第一次输入结束-----
        第一次输出结果---1,2,3,0,0,0
        第二次输入:
        -----第二次输入结束-----
        第二次输出结果---1,2,3,4,5,6
     
     */


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值