1
七、输出函数 printf
八、输入格式转换函数 scanf
2
七、输出函数 printf
printf函数的格式为:
printf ("输出格式控制 ",输出项 1,输出项 2,...);
输出格式控制由转义序列、格式转换说明符和普通字符构成,格式转换说明符由,%”和格式字符组成,如 "%d,%f“
中的 d,f是格式字符。
它们结合在一起指定内存数据的输出格式。普通字符是原样输出的字符。 如:
printf ( "Sum is %d,\n",sum)
中的 Sum 以及逗号是普通字符。
"\n"对应回车换行的转义序列,转义序列的作用是输出控制代码和特殊字符。
3
printf语句就将内存数据项 sum根据格式 %d进行转换并显示出来。输出项是各种有值的表达式。
printf函数可存在一个以上的输出数据,一般输出格式控制的格式转换字符与输出项的个数一致。它们根据各自的次序一一对应,如下所示:
格式转换说明符数多于其后表达式的个数则结果是不确定的,此种情况应予以避免,即禁止 printf ("%d,%f,%d",x,y)
的形式。如果格式转换符数少于表达式的个数,后面多余的表达式将不予转换处理。
printf ("...x =%f,..,y=%x,...z=%d,...\n",x,y,z );
4
1、整型数的格式输出转换
(1) %d或 %i 输出有符号十进制数,根据实际长度输出。 %d与 %i在 scanf系列函数中有所不同。无宽度控制时,多个数据首尾相连地输出。 例如:
printf ("%d,%d",12,12345); //输出 12,12345
(2) %ld,l表示 long型数据的转换,%hd,h表示 short型数据的转换。下面用?醒目地表示空格。
long a=12345678L; short b=4321;
printf ("%9ld,%3hd",a,b);
//输出,?1234565678,4321
printf 函数显示时不保留数据的后缀。后缀用于鉴别数据的确切类型。
5
(3) %wd,%0wd,%-wd 。
%wd 为右对齐方式。 %-wd 为左对齐方式。宽度 w为指定的输出字符个数,如果数据的字符个数小于 w,左段补充空格。
%0wd格式控制中的 0表示输出前导字符 0,左边差额处补 0。
如果数据的字符个数大于 w,输出实际数据的长度。
右对齐方式左补空格,左对齐方式右补空格。
printf ("%5d,%5d",12,123456);
//输出12,123456
printf ("%05d,%05d",12,123456);
//输出 00012,123456
6
(4) %o将整数以 8进制形式输出;
%x将整数以 16进制形式输出;
%u将整数以 10进制形式输出;
这三个格式无论整数是有符号或无符号,一律将二进制数据的最高位作为数据的有效部分转换即视为无符号数输出。
内存数据是二进制的是唯一的,显示的方式则是多样的。
%0wx,%0wu格式控制中的 0表示输出前导字符 0,差额处补 0。输出宽度为 w。
7
[例 ] #include <stdio.h>
void main ()
//定义在函数体中的变量 a,b是局部变量
{ signed short a=65535; // warning,'initializing',
truncation from 'const int' to 'short'
unsigned short b=-1; //-1初始化无符号的短整型数 b
printf ("[%hd,%4hu,%4ho,%x]\n",a,a,a,a);
//输出,[-1,65535,177777,ffffffff]
printf ("[%hd,%4hu,%4ho,%x ]\n",b,b,b,b);
//输出,[-1,65535,177777,ffff ]
} //sizeof (0xffff)= sizeof (-1)=4
8
关于 vc6.0输出的说明:
65535相当于 0x0000ffff,-1是正 1算术负的结果相当于
0xffffffff,这两个整型常数为 4字节的,a,b是两字节的短整型变量,初始赋值 a=65535,b=-1使得 a,b在内存的二进制数据是 16个 1即 1111111111111111。
h修饰符对 a,b内存的二进制数按短整型转换输出,
%hd对内存最高位为 1的数进行间接求补输出 -1。
%hu将内存的最高位视为数据的一部分,因此输出十进制数 65535。
9
[例 ] #include <stdio.h>
//定义在函数外全局范围的变量 a,b是全局变量
signed short a=65535;
// warning,'initializing',truncation from 'const int' to 'short'
unsigned short b=-1;
//-1的内存状态是唯一的,内存状态的解释或输出是多样的
void main ()
{ printf ("[ %d,%u,%010X]\n",a,a,a);
//输出,[-1,4294967295,00FFFFFFFF]
printf ("[%d,%u,%012X]\n",b,b,b);
//输出,[65535,65535,00000000FFFF]
} //int型数据在 32位模式占 4个字节
10
当不存在修饰符 h时,%d,%u输出 int型数据,对于 1
6bit二进制数 1111111111111111;
如果这个数视为有符号的,则带符号扩展,最高位为 1
时扩展为 32为 16进制的 0xffffffff。
如果这个数视为无符号的,则最高的 16位填充以 0,因此扩展为 16进制的 0x0000ffff。
11
2、字符和字符串的输出转换
(1) %c将值在 0~255的整数即 1字节整数以字符方式输出。可以指定格式宽度。例如:
int a=97; printf( "%d,%c ",a,a);
//输出,97,a
char c='c'; printf ("%d,%c ",c,c);
//输出,99,c
char b='b'; printf ("%3d,%3c ",b,b);
//输出,?98,b
printf ("%-3d,% - 3c ",b,b);
//输出,98?,b
12
%3c表示输出占三个字符宽度,前面填充以空格,右对齐方式。 %-3d表示输出占三个字符宽度,后面填充以空格,负号 - 表示左对齐方式。没有宽度控制时,转换的数据相邻输出,不存在对齐方式起作用。
注意,
c是变量,'c'是常数。 %c中的 c是格式字符。
13
[例 ]将转义序列中的一些字符的 ASCII值以 10进制数和字符方式显示出来:
#include<stdio.h>
void main ()
{ char a='\a',b='\b',t='\t',n='\n',v='\v';
//输出结果不含定界符单引号
printf ("%d,%d,%d,%d,%d\n",a,b,t,n,v);
//输出,7,8,9,10,11
printf ("%c,%c,%c\n",'\"','\'','\\');
//输出,",',\
}
14
(2) %s用以输出字符串,实际输出字符串中‘ \0’以前的字符序列,不含定界符双引号。
printf ("%s,%s\n","abcd","12" "34"); //输出,abcd,1234
printf ("%s,%s\n","Ab'\143'","'\101'bc");
//输出,Ab'c','A'bc
printf ("%s,%s\n","\04312","\x23" "\\\143" "04312");
//输出,#12,#\c04312
当若干字符串用空格分隔的时候,相邻的字符串合为一体。 例如:,12”,34”合为,1234” 。
下面代码显示字符串常数中的转义序列字符 \",\t,\\,\n。
printf ("[%s2%s45678]\n","\\\\","\\"); //输出,[\\2\45678]
printf ("[%s10]%s","\"\t'","\n"); //输出,[" '10]
15
(3) %w.rs 右对齐方式;
%-w.rs 负号 -表示左对齐方式;
格式字符 s对应的精度 r是字符串格式转换的最大个数,
超过精度的剩余字符不予处理,剩余的实际上补充为空格。
右对齐方式左补空格,左对齐方式右补空格。宽度格式符 w 控制输出字符占有的宽度个数。
如果精度 r大于宽度 w,则取宽度 w等于精度 r。
16
例如,
printf ("%6s,%3s\n","1234","1234" );
//输出,1234,1234
printf ("%-6s,%-3s","1234","1234" );
//输出,1234,1234
printf ("%6.2s,%3.1s\n","1234567","1234");
//输出,12,1
printf ("%-6.2s,%-3.1s\n","1234567","1234");
//输出,12,1
printf ("%6.7s,%3.4s\n","12345678","12345");
//输出,1234567,1234
17
3、浮点数的格式输出转换
(1) %f 匹配浮点数,转换为 [-]dddd.iiii,dddd和 iiii
是一个或多个十进制数,dddd的个数取决于源数据的大小,iiii数字个数依赖于所给定的精度,缺省值为 6。 例如:
float x=111111.222,y=222222.333;
//文字常数是原始文本串
printf ( "%f,%f\n",111111.222+222222.333,
111111.222f,x+y);
//内存数据是二进制的输出,333333.555000,111111.218750,333333.546875
//输出结果是目标文本串
18
%f 可以匹配 float型数也可以匹配 double型数,在转换时存在数据精度的损失。
系统按照 4舍 5入的原则取舍。 x是 4字节的浮点数,按照 2进制 float格式存贮,%f将 2进制浮点格式存贮的数据转换为文本串。
占 10个字符的文字常数 111111.222是 double型的数据,以 8字节的 2进制 double格式存贮,然后用指定格式转换为目标文本串。
19
(2) %e 有符号的双精度浮点值,该数值以小写字母 e
的科学计数法表示;
%E double类型的数据,该数值表示为:
[-]d.iiiiEsddd。
d是字符 0123456789之一即 d是一个十进制数字,ddd
是三个十进制数构成的组合,iiii是一个或多个十进制数,缺省的数字个数或精度为 6;
s是正号 +或负号 -。方括号 [ ]表示可省略的项。格式字符 e和 E等价,差别只是大小写不同。
一般指数部分 Esddd占五位字符宽度。
20
(3) %g或 %G
以 %f或 %e格式更紧凑地转换有符号的浮点数,如果转换的结果为指数形式后指数值小于 - 4或大于等于预定的精度,用 %e格式实现转换,否则通过 %f格式转换。
双百分号 %%用于显示百分号字符同时屏蔽掉紧跟其后的格式字符 (格式字符当作普通字符 )的转换作用。
没有宽度控制时,转换的数据相邻输出。
21
例如:
printf ("%%e--%e,%%e--%e\n",123456789.0,5e-3);
printf ("%G,%g\t",12345678.9,98765.4321);
printf ("%g,%G\n",0.0000123456789,
0.000123456789);
//输出结果如下
%e--1.234568e+008,%e--5.000000e-003
1.23457E+007,98765.4 1.23457e-005,0.000123457
22
(4) %w.rf,%w.re (右对齐左补空格 )或
% - w.rf,%-w.re (负号 -表示左对齐,右补空格 )
宽度格式符 w是正十进制数,用于控制输出结果的字符个数。输出结果实际的宽度是 w和原先缺少 w时的字符个数的较大值。
如果 w大于原先的字符输出个数,用空格补齐差额。
如果宽度 w带前缀 0则用 0补齐差额。代表负数值的减号占用宽度中的一个字符位置。
精度格式符是一个正十进制数,精度是小数点后面的数字个数,如果前缀 0与前缀负号 -同时出现,0不起作用,即左对齐屏蔽 0的前导作用。
23
例如:
double d=12.123456789;
printf ("[%015f,%-014f ]\n",d,d);
//输出,[ 00000012.123457,12.123457 ]
printf ("[%015.11f,%014.10f]\n",d,d);
//输出,[012.12345678900,012.1234567890]
值得指出不匹配的格式转换输出的结果是不正确的。
例如:
printf ("%4.2f,%d\n",5/4.0,5/4.0); //输出 1.25,0
printf ("%04d,%f\n",1,1); //输出 0001,0.000000
24
4、指针的格式输出转换格式控制转换 %p用于表示内存的地址。
[例 ]格式控制输出地址,0065是局部变量 h,i段地址,
0040是代码段的段地址。
include<stdio.h>
void main (void) //函数名 printf,main为代码的入口地址
{ short h; int i; //&h,&i表示变量 h,i的地址
printf ("&h=%p,&i=%p\n",&h,&i);
//输出 &h=0065FDF4,&i=0065FDF0
printf ("printf=%p,main=%p \n",printf,main);
//输出 printf=004013D0,main=00401005
}
25
八、输入格式转换函数 scanf
格式为,
scanf ("输入格式控制 ",变量地址 1,变量地址 2...,变量地址 n);
输入格式控制包含三类不同的字符内容:
1,格式说明 2,空白字符 3.普通字符格式说明由百分号 %领头,其后跟随格式字符。
对于每一个格式说明都对应一个变量地址参数。
第一个格式说明匹配第一个变量地址,第二个格式说明对应第二个变量地址,依次类推。
经过格式说明规定的转换,从源中提取数据,流入地址对应的变量中,但系统不显示变量的值。
26
普通字符使 scanf函数在数据源中提取数据的时候剔除与这个普通字符相同的字符。 例如:
("%d,%d",&i,&j)
与源流 "12,34"
匹配即应通过键盘键入字符 1,2加上回车,scanf函数在源流中提取一个整型数,然后把接着读入的逗号剔除 (不转换 ),
然后提取下一个整型数。
类似地 ("%d %d",&i,&j)
与源流 "12 34"匹配,
("%d ;%d",&i,&j)
与源流 "12;34"匹配。
27
空白字符使 scanf函数在数据源中提取数据的时候不转换为其后地址对应的变量的字符,scanf函数忽略流中空白字符,空白字符可以是空格、制表符 \t或换行符 \n。
空白字符用来分隔源流中的数据。
scanf函数读取整型常数浮点常数时不添加后缀,后缀作为普通字符处理。
scanf函数从左到右扫描,当遇到普通字符时,就试图去匹配它。
如果不能匹配函数便终止。
如果控制格式与其后的变量匹配不当容易造成停机问题。
28
1.字符和字符串的输入转换
%c转换说明符匹配一个字符变量的地址,不在后面添加‘ \0’字符。
%s转换说明符要求 char*型的地址参数,格式字符 s读取直到下一个空白字符的所有字符,在后面添加‘ \0’字符。
为存储读取的文本串和终止字符‘ \0’,字符数组应足够长。
29
[例 ]通过键盘读取字符
#include<stdio.h>
void main(void)
{ char c1,c2; /*定义两个字符变量 */
printf ("键入两个字符,以逗号分隔 \n");
scanf ("%c,%c",&c1,&c2);
printf ("c1=%c,c2=%c\n",c1,c2);
}
程序运行交互结果:
键入两个字符,以逗号分隔
a,b?
c1=a,c2=b
30
[例 ]通过键盘读取字符
#include<stdio.h>
void main(void)
{ char c1,c2;
printf ("键入两个字符,以分号分隔 \n");
scanf ("%c;%c",&c1,&c2);
printf ("c1=%c,c2=%c",c1,c2);
}
程序运行交互结果:
键入两个字符,以分号分隔
a;b?
c1=a,c2=b
31
2.整型数的输入转换
%d 提取有符号或无符号的十进制数,匹配一个整型变量的地址;
%i 提取有符号或无符号的十进制数、八进制数或十六进制数,匹配整型变量地址;
%o 提取八进制数,匹配无符号整型变量的地址;
%u 提取无符号的十进制数,匹配无符号整型变量的地址 ;
%x (%X) 提取无符号的十六进制数,匹配无符号整型变量的地址
h或 l 前置修饰符 h或 l放在整型格式字符前表示进行
short或 long型整数的转换。
32
[例 ]从键盘输入整型数
#include <stdio.h>
void main (void)
{ short i; int j; long k;
printf ("键入 3个十进制数,");
scanf ("%hd,%d,%ld",&i,&j,&k);
printf ("显示键入的十进制数,%hd,%d,%ld\n",i,j,k);
}
//////////程序交互执行的结果,///////////
键入 3个十进制数,-11,-222,-3333?
显示键入的十进制数,-11,-222,-3333
33
3.浮点数的输入转换浮点数的输入转换与浮点数的输出转换非常类似,不同的是数据的流向互换,作为源的实数不要加相应的后缀
fFlL。
scanf系列函数在源中读取有格式的浮点数,送到地址指向的内存单元,匹配的实参是浮点 float*型的地址。
%e 提取有符号的浮点值,该数值以小写字母 e的科学表示法标识为 [-]d.iiiiesddd ;
%E 读取有符号的浮点值,该数值标识表示为,
[-]d.iiiiEsddd ;
d是一个十进制数字,ddd是三个十进制数构成的组合,iiii是一个或多个十进制数,s是正号 +或负号 - 。
34
%f 读取有符号的浮点值,该数值以小数表示法标识为 [-]dddd.iiii。
dddd和 iiii是一个或多个十进制数。
%g(%G) 提取有符号的浮点值,该值用小数表示法或指数表示法标识的。
1(L) 前置修饰符放在上面浮点格式字符前指示读取
double型的实数。
double 变量地址匹配 scanf中的格式控制串,%lf”,
float 变量地址匹配 scanf中的格式控制串 "%f",printf的格式控制串 "%f"可匹配 double 数据和 float数据。
35
[例 ]输入浮点数
#include<stdio.h>
void main (void)
{ float x,y,z; printf ("键入 3个 float型数,");
scanf ("%e,%f,%g",&x,&y,&z);
printf ("显示键入的 float型数与和,"%g,%e,%f,%f\n",
x,y,z,x+y);
double u,v,w;
printf ("键入 3个 double型数,");
scanf ("%le,%Lf,%lG",&u,&v,&w);
printf ("显示键入的 double数与和,%le,%Lf,%lG,%lf\n",
u,v,w,u+v);
}
36
//程序交互执行的结果 //
键入 3个 float型数,
112233.333,445566.666,778899.123?
显示键入的 float型数与和:
112233,4.4455667e+005,778899.125000,
557799.992188
键入 3个 double型数,
112233.333,445566.666,778899.123?
显示键入的 double型数与和:
1.122333e+005,445566.666000,778899,557799.999000
37