关于scanf函数与printf函数应该注意的点

这里写一下有关scanf函数与printf深入一点了解!废话不多说,直接上干货。

  1. scanf函数

  2. 注意点1:
              首先给出scanf函数的原型:int scanf(const char * restrict format,…); 可以看到,scanf函数其实是有返回值的,是一个int型数据,可能大家几乎没有怎么用到过他的返回值(其实我也没有怎用过,可能我看过的程序还不太多,还没有碰到过。)但是,在这里还是得对它全面了解一哈。这个返回的scanf成功读取的数据项的个数。如果遇到了EOF(即你输入的是ctrl+z),返回的是-1,如果读取发生错误,就会返回0。什么是读取错误捏。意思是你如果有如下语句: 首先给出scanf函数的原型:int scanf(const char * restrict format,…); 可以看到,scanf函数其实是有返回值的,是一个int型数据,可能大家几乎没有怎么用到过他的返回值(其实我也没有怎用过,可能我看过的程序还不太多,还没有碰到过。)但是,在这里还是得对它全面了解一哈。这个返回的scanf成功读取的数据项的个数。如果遇到了EOF(即你输入的是ctrl+z),返回的是-1,如果读取发生错误,就会返回0。什么是读取错误捏。意思是你如果有如下语句:
    int a=10;
    int num=scanf("%d\n",&a);
    但是你却输入的非数字,例如字符a,就会导致scanf函数读取错误。scanf函数就会返回0。

  3. 注意点2:
            说完了返回值类型,现在来谈一下scanf中转换字符为%c时应该注意的一些地方。大家都知道,scanf函数在输入时是会跳过空白字符(空格,Tab键,enter键),但是对于scanf中为%c时,这些是都不会跳过的。什么意思捏。就是如果你有如下代码:
    char ch1;
    char ch2;
    int num=scanf("%c%c",&ch1,&ch2);
    printf(“ch1=%c ch2=%c num=%d”,ch1,ch2,num);
    如果你输入 a(空格)s(回车)这个样子,我知道大家是想要将a赋值给ch1,s赋值给ch2。但是你会发现,其实ch1==‘a’,但是ch2的确是你输入的空格。这个就是我想说的,scanf在转换说明符为%c时,是不会忽略你所输入的空白字符的。所以,ch2接受的就是空格。那么,解决方式是什么捏?这里给大家介绍几种方法。
     方法一:scanf("%c%*%c",&ch1,&ch2);这里的% *就是说忽略两个字符之间的东西, * 就是通配的意思。在C Primer Plus(第五版)中是这么说的,在scanf()中 * 提供了截然不同的服务。当把它放在%和说明字符之间时,它使函数跳过相应的输入项目
     方法二:scanf("%c %c",&ch1,&ch2);在这里我的两个%c之间时会有一个空格的(可能大家看到的不是特别清楚)这个的用意也是使scanf()跳过中间的那个空格。为什么这样写就可以跳过空格捏。在scanf()函数中转换字符间输入非转换字符,那么你在输入时也得去输入同样的字符才行。用百度百科上面的一句话就是:如果格式控制串中有非格式字符则输入时也要输入该非格式字符。 你可能写过这样的scanf();
    int a,b,c;
    scanf("%d,%d",&a,&b);
    然后,你发现输入1,2才是正确的(这个强调的是在两个输入数据之间使用‘,’(逗号)分开。)这里的道理和上面说的一样,在转换字符间输入非转换字符,所以你输入的时候还要输入一个 , 。(提醒一哈小白,不要认为所有的数据都是用, 来分割的)如果你想要弄清楚,其中的原理是什么,可能就要去看scanf()的源码了。
      对于scanf()来说,输入一个字符串,我们也得花一番心思了。一般来说,你可能会这么写:
    char str[80];
    scanf("%s", str);/ * 此处输入:I love you! */
    你就会发现你输入的 I love you! 最后打印出来只有l ,这个是为什么捏。就在于,%s也是会遇到空白字符就会停止读取。所以,你打印的就只有l了。所以,解决方法是:最好的方法是使用fgets()函数。可不要使用gtes()函数。当然还有别的方法:这个方式是在百度百科上看到的。scanf("%[^\n]",str);这个样子就好了。如果你对[ ^\n ]不了解的话,文章末我会放上相关资料。

  4. 注意点3:
            scanf和缓冲有关的问题。可能大家都遇到过:
    int a=10;
    char ch;
    scanf("%d",&a);
    scanf("%c",&ch);
    然后你输入数据后发现,怎么我还没有输入第二个数据,就结束输入了。原因就是scanf()缓冲的问题,这里仅仅介绍一哈scanf()的行缓冲。
    行缓冲 :
    当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是标准输入(stdin)和标准输出(stdout)。
    所以说,你输入的回车没有被scanf()函数认为是分割符,而是被下一个%c所接收走了,因为scanf()是行缓冲,所以你输入一个回车就结束本次scanf()了。为了克服这个问题。也有几个方法:
     方法一:fflush(stdin);可移植性不强。这个是微软公司自己定义的,不在c的标准库里。
     方法二:万能清空缓存语句。
    while((ch = getchar()) != ‘\n’ && ch != EOF);这个是十分推荐大家使用的。那么你的程序写成:
    scanf("%d",&a);
    while((ch = getchar()) != ‘\n’ && ch != EOF);
    scanf("%c",&ch);
    就可以了。
     方法三:其实还有一个简单的方法:直接写成:
    scanf("%d",&a);
    getchar();
    scanf("%c",&ch);
    就好了。

  5. printf函数
          函数原型:int printf(const char *format,…);

  6. 注意1:
          printf()函数特别要注意的地方就是转化说明符的使用。上一个例子大家就比较清楚了。
    printf("%c",97);
    printf("%c",336);
    大家都知道第一个会打印出a,因为a的ASCII码与97对应,但是这个336没有与之对应的。那编译器是怎么处理的捏。此时编译器是会发生截断的。即336的二进制为:0000 0001 0101 0000 而%c编译器解释的是char,所以他将仅仅只要一个字节的数据,即后面8位。而这个变成十进制数为80,对应的为字符P,所以将会打印P。这里引用C Primer Plus书本上的一句话:更技术一点,您可以说,该数字被解释为“以256为模”,意即使用数字被256除的余数。(336%256=80)

  7. 注意2:
          当然,最恐怖的是你如果写成这样的代码,可能结果就会十分奇怪了。
    int a=10;
    printf("%f\n",a);
    double b=10;
    printf("%d\n",b);
    你就会发现你的结果为0(0.000000)。这个原因也是因为数据在电脑中存贮的方式二进制,分为有符号与无符号。这里就不多讲了。一定要注意的是,使用printf()函数时,一定要记得数据类型之间要配套使用。

这里是我参考过的文章:大家也可以去看看!
老师也说坚持写博客是十分好的习惯,所以,我希望你可以坚持下去!
https://blog.csdn.net/qq_26768741/article/details/50933598
https://baike.baidu.com/item/scanf/10773316?fr=aladdin#5_3
https://blog.csdn.net/qingkong8832/article/details/6667701

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值