前言
在C语言中,printf和scanf函数是贯穿始终的,它们是输出和输入函数,简称I/O函数。它们的工作原理几乎相同,两个函数都使用格式字符串和参数列表。我们先介绍printf(),再介绍scanf()。
printf()
printf函数格式:
printf( 格式字符串, 待打印项1, 待打印项2,…)
格式字符串是用双引号括起来的语句,待打印项是要打印的项,它们可以是变量、常量,甚至是在打印之前先要计算的表达式。
转换说明符
我们在使用中,经常会用到%d和%c来打印想要的整数和字符,这些以%+字母称之为转换说明,下面给出给出一些转换说明和输出类型表
下面通过一些例子来演示这些转换说明的使用
#include<stdio.h> int main() { int number=9; int cost=500; float pi=15.67; printf("今天消费了%d,欠了别人%f钱\n",cost,pi); printf("这里有%d个篮球,总共花费了%c%d\n",number,'$',2*cost); return 0; }
结果:
这里的
printf(“这里有%d个篮球,总共花费了%c%d\n”,number,‘$’,2*cost);
第二个打印项是字符常量,第三个是乘法表达式,表明printf()使用的是值
要清楚,格式字符串要和转换字符对应清楚,否则将会导致严重的后果。
如:
printf(“今天买了%d个篮球,花了%d元”,number);
结果:
今天买了9个篮球,花了1867835296元
这里的第二个%d没有对应的值,所以打印出来的是一个毫无意义的值,系统不同,结果也会不同。
由于%用来表示转换说明,所以当要打印%时,要用到%%进行打印
printf(“今天有%%95的概率会下雨\n”);
结果:今天有%95的概率会下雨
转换说明修饰符
在%和转换字符之间插入修饰符可修饰基本的转换说明。下面给出修饰符表格:
下面通过例子来说明使用含义。
字段宽度:
*号表示字段开始和结束
#include<stdio.h> int main() { int num=8848; printf("%d\n",num); printf("%2d\n",num); printf("%9d\n",num); printf("%-9d\n",num); return 0; }
说明:第一项是默认的打印结果,输出结果默认是对应相应的字段宽度。
第二项由于字段宽度小于实际宽度,故字段宽度会默认扩大到相应的宽度。
第三项是默认是右对齐,第四项的-表示是左对齐。
浮点型格式:
#include <stdio.h> int main() { const double op = 3456.78; // const变量 printf("*%f*\n", op); printf("*%e*\n", op); printf("*%4.2f*\n", op); printf("*%3.1f*\n", op); printf("*%10.3f*\n", op); printf("*%10.3E*\n", op); printf("*%+4.2f*\n", op); printf("*%010.2f*\n", op); return 0; }
说明:第一项是默认的转换说明,f默认打印小数点后6位,超出则以四舍五入的方式计算打印。第二项是的e表示10的几次方再乘上前面的数字。第三项的.2表示打印小数点后两位,超出以四舍五入方式进行计算打印。第五项10为字段宽度。第6项E与e是相同作用的,.3为小数点后3位,10为字段宽度。第7项0是进行补充字段宽度空白处的。
格式标记:
#include <stdio.h> int main() { printf("%x %X %#x\n", 78, 78, 78); printf("**%d**% d**% d**\n", 42,42, - 42); printf("**%5d**%5.3d**%05d**%05.3d**\n", 6, 6, 6, 6); return 0; }
说明:第一句0x通常表示这是一个地址,用#来进行修饰。第二句当空格遇到负号时,空格无效。第三句.3表示打印整型格式的精度,当0和.3一起使用时,0的修饰会被省略。
字符串:
#include<stdio.h> int main() { char arr[]="Today is a sun day"; printf("[%s]\n",arr); printf("[%25s]\n",arr); printf("[%.5s]\n",arr); printf("[%25.5s]\n",arr); printf("[%-25.5s]\n",arr); return 0; }
说明:.5表示打印字符串长度,25为字段宽度,默认右对齐,加上-表示左对齐。
在我们使用转换说明时,用对字符是非常关键的。我们知道,电脑将会以二进制的格式进行存储,不同的转换说明是将二进制格式转换为不同形式进行改变再打印到屏幕上。
如将字符打印成整数
printf(“%d\n”,‘a’);
结果:97
它会通过ASCLL编码表进行转换从而打印
再如:
将整数用%f打印
printf(“%f\n”,16);
结果:0.000000
16对于%f来说相当于0,所以要正确打印的话,要用16.0表示你是一个有精度的数。
printf()的返回值
大部分C函数都有一个返回值,这是函数计算并返回给主程序的值。printf()函数也有一个返回值,它返回打印字符的个数。如果有输出错误,printf()则返回一个负值。
#include<stdio.h> int main() { int num1=printf("%d\n",3); int num2=printf("这个数是%d\n",3); printf("%d %d",num1,num2); return 0; }
说明:中文表示两个字符,%d和\n分别各表示一个。所以长度取决于格式字符串的长度。
scanf()
接下来我们来看scanf函数。这是C语言中最通用的一个C函数,因为它可以读取不同格式的数据。我们键盘上只能输入字母,字符和数字,scanf函数能将输入的字符串转换成整数、浮点数、字符或字符串,这种方式恰好于printf()相反。格式形式和printf类似,也使用格式字符串和参数列表。scanf()中的格式字符串表明字符输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()函数使用变量、常量和表达式,而scanf()函数使用指向变量的指针。一般来说,对基本变量的使用赋值,用在变量前加一个&(意思为取地址);字符串数组本质其实就是一个指针,所以不要使用&。
#include<stdio.h> int main() { int n; char arr[30]; scanf("%d",&n);//n为基本变量,需要应用& scanf("%s",arr);//arr是一个数组,不需要用到& return 0; }
对于转换说明,于printf类似。
对于scanf()函数也有修饰符,但对于使用场所来说,是比较少的,所以在此没有介绍。一般使用场景就如我上面的例图一般。
scanf的输入
我们以%d读取一个整数为例。我们输入一个数字(2048),会先放在一块输入空间里,对于scanf(),会去这块空间进行读取,读取到空白字符会跳过,直至读到数字或者符号(+或-),会将这个数字字符进行保存,接着读下一个字符,当下一个字符是非空白字符,继续读取保存,直至读到空白字符停止下来。
倘若在这块输入空间最前头有某一个非空白非数字字符,遇到时将会读取,由于不是数字,将会还给输入空间。scanf继续读下一个字符,又读到这个非数字字符,以此往复,无法给变量进行赋值。
当我们了解这些之后,当我们有多个变量需要赋值,通常会用换行符和空格进行对下一个变量的赋值。
当然,如果设定了字段宽度,scanf()会在字段结尾或第1个空白字符处停止读取(满足两个条件之一便停止)。
#include<stdio.h> int main() { int n; scanf("%2d",&n); printf("%d",n); return 0; }
结果:
输入:2018
输出:20
当我们以这种形式输入时:
scanf(“%d,%d”,&n);
要严格按照格式字符串的格式进行输入
3,3
3 , 3
3,
3
这三种格式都行,只要带有逗号输入即可,倘若没有逗号,那么就会输出没有意义的值。
#include<stdio.h> int main() { int n,m; scanf("%d,%d",&n,&m); printf("%d %d",n,m); return 0; }
scanf()的返回值
scanf()函数返回成功读取的项数。如果没有读取任何项,且需要读取一
个数字而用户却输入一个非数值字符串,scanf()便返回0。当scanf()检测
到“文件结尾”时,会返回EOF(EOF是stdio.h中定义的特殊值,通常用
#define指令把EOF定义为-1)。
所以当我们想要多次进行赋值时,可以用while语句,然后以等于EOF作为结束条件。在VScode(gcc)编译环境下以CTRL+z作为EOF。
#include<stdio.h> int main() { int n; while(scanf("%d",&n)!=EOF) { printf("%d\n",n); } return 0; }
返回值:
#include<stdio.h> int main() { int n,m; int sum=scanf("%d,%d",&n,&m); printf("%d ",sum); return 0; }