程序2-1和程序2-2都使用了格式化输出函数printf()来输出运算的结果,此函数位于标准C语言库中,其函数原型在头文件stdio.h中,所以在程序开头要加上文件包含指令:
#include<stdio.h>
pirntf()函数的标准格式为:
printf("格式控制串",输出参数表);
格式控制串是指定数据的输出格式,格式控制串由格式字符(包括转换说明符、标志、域宽、精度)和普通字符组成。转换说明符和百分号(%)一起使用,用来说明内存中数据的输出格式。例如说明符%d指定printf()函数把int型数值从二进制形式转换成十进制整数,转换说明符%f是对float型数值进行类似的转换。普通字符在输出时原样输出(在显示时可起到提示作用)。
输出参数表是指待输出的数据,可以是常量、变量或其他更复杂的表达式,也可以没有输出项。当有多个输出项时,各输出项之间用逗号隔开。输出项必须与格式字符在类型和数量上完全对应。
1.输出格式中的普通字符
当printf()函数的参数只有“格式控制串”,且“格式控制串”中没有格式字符而只有普通字符时,函数完成的功能是将双引号中的字符串原样输出(显示在屏幕上)。例如:
printf("hello C !");
此句是将“hello C !”在显示器屏幕上原样输出。
2.输出格式中的转换字符串
转换说明符规定了对应输出项的输出类型,即将输出的数据转换为指定的格式输出。该项不能省略。格式为:
%转换说明符
常用的转换字符串及其说明如表2-2所示。
表2-2 常用的转换字符串
例如:
int visitorCount=150;
printf("%d",visitorCount);
输出结果为:150。
3.输出格式中的宽度修饰符
宽度修饰符用一个十进制整数来表示输出数据的位数,插在%与转换说明符之间,其作用是控制打印数据的宽度,也称为“域宽”。
·%md代表数据以十进制整数形式输出,宽度占m列,数据不足m列的左补空格,超过m列的情况下按实际位数输出。例如:
int salary=5500;
printf("%10d",salary);
输出结果为: 5500。
输出结果中数值占4位,靠右对齐,左边有6个空格。
·%-md代表数据以十进制整数形式输出,宽度占m列,数据不足m列的右补空格,超过m列的情况下按实际位数输出。例如:
int salary=5500;
printf("%-10d",salary);
输出结果为:5500 。
输出结果中数值占4位,左对齐,右边有6个空格。
解决问题:输出整数幂
输入两个正整数m和n,分行输出m和n的值及其2次方和3次方,要求每个数据占8列,左对齐。例如,若输入: 11 41 ,则输出如下:
11 121 1331
41 1681 68921
解题思路:
(1)m的2次方可以使用表达式m*m计算,m的3次方可以用表达式m*m*m计算,尽管有计算幂的库函数pow,但因为其计算结果不是int类型,此处不建议使用。
(2)题目要求“每个数据占8列,左对齐”,可使用格式控制字符串“%-8d”:
printf("%-8d%-8d%-8d\n",m,m*m,m*m*m);
注意,若要严格控制每个数据占8列,则每个“%-8d”后面不要再随意加入空格,否则列宽就多于8列了。
/*程序2-3:输出整数幂*/
从键盘读取数据的最灵活的方法是使用库函数scanf()。scanf()函数从标准输入(键盘)读取信息,按照格式描述把读入的信息转换为指定数据类型的数据,并把这些数据存入指定的内存区域中。例如语句:
scanf("%d",&fahr);
从键盘读取一个十进制整数,并将其赋给int型变量fahr。%d为格式转换符,每个格式转换符对应后面的一个内存地址。scanf()从标准输入流按指定格式读取数据,然后转换为机内码存入对应内存地址。变量名前的"&"是地址运算符,作用是获取变量的地址。
scanf()函数的格式:
scanf(格式控制字符串,内存地址1,内存地址2,…,内存地址n)
整型变量有6种不同类型,整型常量有不同进制的书写方法,而%d仅适合于为int类型变量读入十进制表示的数据。为了读写无符号整数、短整数、长整数以及十进制和八进制数,需要一些新的转换说明符。
(1)格式符d、i、u、o、x:
%d或%i以十进制有符号整数形式转换输入数据;
%u以十进制无符号整数形式转换输入数据;
%o以八进制有符号整数形式转换输入数据;
%x或%X以十六进制有符号整数形式转换输入数据。
(2)h或l前缀:
读入短整数时,加前缀字母h,如%hd;
读入长整数时,加前缀字母l,如%ld;
(3)读入64位整数:
如果编译器支持__int64,用格式符%I64d,如果编译器支持long long,用格式符%lld。
(4)宽度:
用十进制整数指定输入的宽度(即字符数)。例如:
scanf("%5d",&a);
输入:12345678
只把12345赋予变量a,其余部分被截去。
(5)赋值抑制符号*:
用以表示该输入项读入后不赋予相应的变量,即跳过该输入值。例如:
scanf("%d %*d %d",&a,&b);
当输入为:1 2 3时,把1赋予a,2被跳过,3赋予b。
很多时候程序要从已有的文件中读入数据,文件只能顺序读取,经常需要在读入时跳过某些不需要的信息。例如读入某人的18位身份证号,输出其出生日期可用语句:
scanf("%*6d%4d%2d%2d%*d",&year,&month,&day);
printf("%4d-%2d-%2d",year,month,day);
这段代码将18位的身份证号分为几个部分读入:用%*6d将从缓冲区读入6个数字,但不存储,接着由%4d读入4个数字存入year,然后读入两位数字存入month,再读入两位数字存入day,最后用%*d将其余数字从缓冲区读入,但不存储。若输入:
410102197805210123
则输出:
1978-05-21