C语言----输入scanf和输出printf详解

        C语言编程中,输入输出是基本操作,printf和scanf并不是C语言中的唯一的输入输出选择,对于输入有scanf()、getchar()、getche()、getch()、gets();对于输出有printf()、puts()、putchar(),他们各有自己的使用场景,本篇文章主要介绍常用的scanf和printf

一:scanf详解

scanf 是 scan format 的缩写,意思是格式化扫描,也就是从键盘获得用户输入

1,格式化输入

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    //输入一个整数
    int a;
    scanf("%d",&a);
    printf("a = %d\n",a);
    getchar();

    //输入一个字符
    char b;
    scanf("%c",&b);
    printf("b = %c\n",b);
    getchar();

    //输入一个字符串
    char c[10] = {0};
    scanf("%s",c);
    printf("c = %s\n",c);
}

运行结果:

 上面的举例是scanf的基本用法,看到上面的例子有同学就有疑问了为什么两次输入之间要有getchar(),这个后面会讲到。对于scanf输入有严格的格式控制符,如下

格式控制符说明
%c读取一个单一的字符
%hd、%d、%ld读取一个十进制整数,并分别赋值给 short、int、long 类型
%ho、%o、%lo读取一个八进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
%hx、%x、%lx读取一个十六进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
%hu、%u、%lu读取一个无符号整数,并分别赋值给 unsigned short、unsigned int、unsigned long 类型
%f、%lf读取一个十进制形式的小数,并分别赋值给 float、double 类型
%e、%le读取一个指数形式的小数,并分别赋值给 float、double 类型
%g、%lg既可以读取一个十进制形式的小数,也可以读取一个指数形式的小数,并分别赋值给 float、double 类型
%s读取一个字符串(以空白符为结束)

2,带空格输入到多个变量

#include <stdio.h>
#include <stdlib.h>

int main()
{
    //输入一个整数
    int a, b, c;
    scanf("%d %d", &a, &b);
    printf("a=%d, b=%d\n", a,b);
    scanf("%d   %d", &a, &b);
    printf("a=%d, b=%d\n", a,b);
    scanf("%d, %d, %d", &a, &b, &c);
    printf("a=%d, b=%d, c=%d\n", a,b,c);
   
    scanf("%d not equal %d", &a, &b);
    printf("a=%d, b=%d\n", a,b);
    
}

运行结果:

         第一个 scanf() 的格式控制字符串为"%d %d",中间有一个空格,而我们却输入了1       2,中间有多个空格。第二个 scanf() 的格式控制字符串为"%d   %d",中间有多个空格,而我们却输入了1 2,中间只有一个空格。这说明 scanf() 对输入数据之间的空格的处理比较宽松,并不要求空格数严格对应,多几个少几个无所谓,只要有空格就行。

        用户每次按下回车键,程序就会认为完成了一次输入操作,scanf() 开始读取用户输入的内容,并根据格式控制字符串从中提取有效数据,只要用户输入的内容和格式控制字符串匹配,就能够正确提取。

         本质上讲,用户输入的内容都是字符串,scanf() 完成的是从字符串中提取有效数据的过程

3,连续输入到数组

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[5];
    int i = 0;
    for(i=0; i<5; i++)
    {
        scanf("%d",a+i);
    }
    for(i=0; i<5; i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
}

运行结果:

 4,带空格的字符串输入

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char str[100];
    scanf("%[^\n]",str);//以换行符作为字符串输入的结束
    printf("%s\n",str);
}

运行结果:

 利用格式符"%[^]",可以输入带空格的字符串到数组。需要注意的是方括号里边的^后面的字符表示的是输入的结束符,如同默认情况下空格和回车键以及TAB键是作为字符串输入的结束符一样,利用此格式符便相当于由编程者自己指定一个输入结束符。

5,刷题常用的对同一变量连续输入

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a;
    while(scanf("%d",&a)!=EOF)
    {
        printf("a = %d\n",a);
    }
}

         EOF在scanf连用时代表-1的意思,当用到while(scanf()!=EOF),代表的意思是一直输入,直到scanf返回的值是-1时才会停止输入,也可以在while里面加上一些约束条件,使输入在特定的条件下就会停止,也可以在输入完成后按下Ctrl+z,可以强行停止输入

6,scanf输入的本质

        从本质上讲,我们从键盘输入的数据并没有直接交给 scanf(),而是放入了缓冲区中,直到我们按下回车键,scanf() 才到缓冲区中读取数据。如果缓冲区中的数据符合 scanf() 的要求,那么就读取结束;如果不符合要求,那么就继续等待用户输入,或者干脆读取失败。

        需要注意的是如果缓冲区中的数据不符合 scanf() 的要求,要么继续等待用户输入,要么就干脆读取失败。

        问题回到了1章节,为什么要在每个输入后面加个getchar(),如果不加运行结果如下:

         出现这种现象就是和缓冲区有关,当我们按下enter键的时候,缓冲区里是有enter的控制符,会当做第二次scanf的输入,所以需要用getchar去清除缓冲区里的enter控制符。

二:printf详解

printf() 是最灵活、最复杂、最常用的输出函数

1,printf的基本用法

printf 函数原型为int printf(const char *fmt, ...),使用了可变参数的模式

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a = 10;
    char b = 'b';
    float c = 9.99;
    printf("%d %c %f\n",a,b,c);
}

对于基本printf的用法需要注意的是格式控制符,对变量以什么样的形式输出

格式控制符说明
%c输出一个单一的字符
%hd、%d、%ld以十进制、有符号的形式输出 short、int、long 类型的整数
%hu、%u、%lu以十进制、无符号的形式输出 short、int、long 类型的整数
%ho、%o、%lo以八进制、不带前缀、无符号的形式输出 short、int、long 类型的整数
%#ho、%#o、%#lo以八进制、带前缀、无符号的形式输出 short、int、long 类型的整数
%hx、%x、%lx
%hX、%X、%lX
以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。
%#hx、%#x、%#lx
%#hX、%#X、%#lX
以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。
%f、%lf以十进制的形式输出 float、double 类型的小数
%e、%le
%E、%lE
以指数的形式输出 float、double 类型的小数。如果 e 小写,那么输出结果中的 e 也小写;如果 E 大写,那么输出结果中的 E 也大写。
%g、%lg
%G、%lG
以十进制和指数中较短的形式输出 float、double 类型的小数,并且小数部分的最后不会添加多余的 0。如果 g 小写,那么当以指数形式输出时 e 也小写;如果 G 大写,那么当以指数形式输出时 E 也大写。
%s输出一个字符串

2,固定宽度输出

对于要输出固定宽度并且要对齐的矩阵式数据,printf也是可以轻松搞定的

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a1=11, a2=111, a3=1111, a4=11111;
    int b1=2, b2=22, b3=222, b4=2222;
    int c1=33333, c2=333, c3=33, c4=3;
    int d1=666666, d2=66, d3=66666, d4=6666;
    printf("%-10d %-10d %-10d %-10d\n", a1, a2, a3, a4);
    printf("%-10d %-10d %-10d %-10d\n", b1, b2, b3, b4);
    printf("%-10d %-10d %-10d %-10d\n", c1, c2, c3, c4);
    printf("%-10d %-10d %-10d %-10d\n", d1, d2, d3, d4);
}

运行结果:

 printf() 格式控制符的完整形式如下

%[flag][width][.precision]type

[ ] 表示此处的内容可有可无,是可以省略的。

 1) type 表示输出类型,比如 %d、%f、%c、%lf,type 就分别对应 d、f、c、lf;再如,%-10d中 type 对应 d。type 这一项必须有,这意味着输出时必须要知道是什么类型。

2) width 表示最小输出宽度,也就是至少占用几个字符的位置;例如,%-10d中 width 对应 10,表示输出结果最少占用 9 个字符的宽度。

当输出结果的宽度不足 width 时,以空格补齐(如果没有指定对齐方式,默认会在左边补齐空格);当输出结果的宽度超过 width 时,width 不再起作用,按照数据本身的宽度来输出。

3) .precision 表示输出精度,也就是小数的位数。

  • 当小数部分的位数大于 precision 时,会按照四舍五入的原则丢掉多余的数字;
  • 当小数部分的位数小于 precision 时,会在后面补 0。


另外,.precision 也可以用于整数和字符串,但是功能却是相反的:

  • 用于整数时,.precision 表示最小输出宽度。与 width 不同的是,整数的宽度不足时会在左边补 0,而不是补空格。
  • 用于字符串时,.precision 表示最大输出宽度,或者说截取字符串。当字符串的长度大于 precision 时,会截掉多余的字符;当字符串的长度小于 precision 时,.precision 就不再起作用。

4) flag 是标志字符。例如,%#x中 flag 对应 #,%-10d中 flags 对应-。下表列出了 printf() 可以用的 flag:

标志字符含  义
--表示左对齐。如果没有,就按照默认的对齐方式,默认一般为右对齐。
+用于整数或者小数,表示输出符号(正负号)。如果没有,那么只有负数才会输出符号。
空格用于整数或者小数,输出值为正时冠以空格,为负时冠以负号。
#
  • 对于八进制(%o)和十六进制(%x / %X)整数,# 表示在输出时添加前缀;八进制的前缀是 0,十六进制的前缀是 0x / 0X。
  • 对于小数(%f / %e / %g),# 表示强迫输出小数点。如果没有小数部分,默认是不输出小数点的,加上 # 以后,即使没有小数部分也会带上小数点。

 

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ftzchina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值