第二章 基本元素、类型和概念 七、输出函数printf 八、输入格式转换函数scanf
七、输出函数printf printf函数的格式为: printf ("输出格式控制",输出项1,输出项2,...); 输出格式控制由转义序列、格式转换说明符和普通字符 构成, 格式转换说明符由“%”和格式字符组成,如"%d,%f“ 中的d,f是格式字符。 它们结合在一起指定内存数据的输出格式。普通字符是 原样输出的字符。如: printf ( "Sum is %d,\n", sum) 中的Sum 以及逗号是普通字符。 "\n"对应回车换行的转义序列,转义序列的作用是输出控制 代码和特殊字符。
printf ("...x =%f, ... y=%x, ...z=%d,...\n", x, y, z ); printf语句就将内存数据项sum根据格式%d进行转换 并显示出来。输出项是各种有值的表达式。 printf函数可存在一个以上的输出数据,一般输出格式 控制的格式转换字符与输出项的个数一致。它们根据各自的 次序一一对应,如下所示: 格式转换说明符数多于其后表达式的个数则结果是不确 定的,此种情况应予以避免,即禁止 printf ("%d, %f,%d",x, y) 的形式。如果格式转换符数少于表达式的个数,后面多余的 表达式将不予转换处理。 printf ("...x =%f, ... y=%x, ...z=%d,...\n", x, y, z );
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 函数显示时不保留数据的后缀。后缀用于鉴别数 据的确切类型。
(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
(4) %o将整数以8进制形式输出; %x将整数以16进制形式输出; %u将整数以10进制形式输出; 这三个格式无论整数是有符号或无符号,一律将二进制数据的最高位作为数据的有效部分转换即视为无符号数输出。 内存数据是二进制的是唯一的,显示的方式则是多样的。 %0wx , %0wu格式控制中的0表示输出前导字符0,差额处补0。输出宽度为w。
[例] #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
关于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。
[例] #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个字节
当不存在修饰符h时,%d,%u输出int型数据,对于1 6bit二进制数1111111111111111; 如果这个数视为有符号的,则带符号扩展,最高位为1 时扩展为32为16进制的0xffffffff。 如果这个数视为无符号的,则最高的16位填充以0,因 此扩展为16进制的0x0000ffff。
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
%3c表示输出占三个字符宽度,前面填充以空格,右对齐 方式。%-3d表示输出占三个字符宽度, 后面填充以空格,负 号 - 表示左对齐方式。没有宽度控制时,转换的数据相邻输 出,不存在对齐方式起作用。 注意: c是变量,'c'是常数。%c中的c是格式字符。
[例]将转义序列中的一些字符的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",'\"','\'','\\'); //输出: ",',\ }
(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]
(3) %w.rs 右对齐方式; %-w.rs 负号-表示左对齐方式; 格式字符s对应的精度r是字符串格式转换的最大个数, 超过精度的剩余字符不予处理,剩余的实际上补充为空格。 右对齐方式左补空格,左对齐方式右补空格。宽度格式 符 w 控制输出字符占有的宽度个数。 如果精度r大于宽度w,则取宽度w等于精度r。
例如: 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
3、浮点数的格式输出转换 (1) %f 匹配浮点数,转换为[-]dddd.iiii,dddd和 iiii 小,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 //输出结果是目标文本串
%f 可以匹配float型数也可以匹配double型数,在转换 时存在数据精度的损失。 系统按照4舍5入的原则取舍。x是4字节的浮点数,按 照2进制float格式存贮,%f将2进制浮点格式存贮的数据转 换为文本串。 占10个字符的文字常数111111.222是double型的数 据,以8字节的2进制double格式存贮,然后用指定格式转 换为目标文本串。
(2) %e 有符号的双精度浮点值,该数值以小写字母e 的科学计数法表示; %E double类型的数据,该数值表示为: [-]d.iiiiEsddd。 d是字符0123456789之一即d是一个十进制数字,ddd 是三个十进制数构成的组合,iiii是一个或多个十进制数,缺 省的数字个数或精度为6; s是正号+或负号-。方括号[ ]表示可省略的项。格式字 符e和E等价,差别只是大小写不同。 一般指数部分Esddd占五位字符宽度。
(3) %g或%G 以%f或%e格式更紧凑地转换有符号的浮点数,如果转 换的结果为指数形式后指数值小于- 4或大于等于预定的精 度,用%e格式实现转换,否则通过%f格式转换。 双百分号%%用于显示百分号字符同时屏蔽掉紧跟其后 的格式字符(格式字符当作普通字符)的转换作用。 没有宽度控制时,转换的数据相邻输出。
例如: 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
(4) %w.rf , %w.re (右对齐左补空格)或 个数。输出结果实际的宽度是w和原先缺少w时的字符个数 的较大值。 如果w大于原先的字符输出个数,用空格补齐差额。 如果宽度w带前缀0则用0补齐差额。代表负数值的减号 占用宽度中的一个字符位置。 精度格式符是一个正十进制数,精度是小数点后面的数 字个数,如果前缀0与前缀负号-同时出现,0不起作用,即 左对齐屏蔽0的前导作用。
例如: 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
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 }
八、输入格式转换函数scanf 格式为: scanf ("输入格式控制",变量地址1,变量地址2.... 变量地址n); 输入格式控制包含三类不同的字符内容: 1. 格式说明 2. 空白字符 3.普通字符 格式说明由百分号%领头,其后跟随格式字符。 对于每一个格式说明都对应一个变量地址参数。 第一个格式说明匹配第一个变量地址,第二个格式说明 对应第二个变量地址,依次类推。 经过格式说明规定的转换,从源中提取数据,流入地址 对应的变量中,但系统不显示变量的值。
普通字符使scanf函数在数据源中提取数据的时候剔除 与这个普通字符相同的字符。例如: ("%d, %d", &i, &j) 与源流 "12,34" 匹配即应通过键盘键入字符1,2加上回车,scanf函数在源流 中提取一个整型数,然后把接着读入的逗号剔除(不转换), 然后提取下一个整型数。 类似地 ("%d %d", &i, &j) 与源流 "12 34"匹配, ("%d ;%d", &i,&j) 与源流 "12;34"匹配。
空白字符使scanf函数在数据源中提取数据的时候不转 字符,空白字符可以是空格、制表符\t或换行符\n。 空白字符用来分隔源流中的数据。 scanf函数读取整型常数浮点常数时不添加后缀,后缀 作为普通字符处理。 scanf函数从左到右扫描,当遇到普通字符时,就试图 去匹配它。 如果不能匹配函数便终止。 如果控制格式与其后的变量匹配不当容易造成停机问 题。
1.字符和字符串的输入转换 %c转换说明符匹配一个字符变量的地址,不在后面添 加‘\0’字符。 %s转换说明符要求char*型的地址参数,格式字符s读 取直到下一个空白字符的所有字符, 在后面添加‘\0’字符。 为存储读取的文本串和终止字符‘\0’,字符数组应足够 长。
[例]通过键盘读取字符 #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
[例]通过键盘读取字符 #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
2.整型数的输入转换 %d 提取有符号或无符号的十进制数,匹配一个整型 变量的地址; %i 提取有符号或无符号的十进制数、八进制数或十六 进制数,匹配整型变量地址; %o 提取八进制数, 匹配无符号整型变量的地址; %u 提取无符号的十进制数,匹配无符号整型变量的地 址; %x (%X) 提取无符号的十六进制数,匹配无符号整型 变量的地址 h或l 前置修饰符h或l放在整型格式字符前表示进行 short或long型整数的转换。
[例]从键盘输入整型数 #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
3.浮点数的输入转换 浮点数的输入转换与浮点数的输出转换非常类似,不 同的是数据的流向互换,作为源的实数不要加相应的后缀 fFlL。 scanf系列函数在源中读取有格式的浮点数,送到地址 指向的内存单元,匹配的实参是浮点float*型的地址。 %e 提取有符号的浮点值,该数值以小写字母e的科 学表示法标识为[-]d.iiiiesddd ; %E 读取有符号的浮点值,该数值标识表示为: [-]d.iiiiEsddd ; d是一个十进制数字,ddd是三个十进制数构成的组 合,iiii是一个或多个十进制数,s是正号+或负号 - 。
%f 读取有符号的浮点值,该数值以小数表示法标识 为[-]dddd.iiii。 dddd和 iiii是一个或多个十进制数。 %g(%G) 提取有符号的浮点值,该值用小数表示法或 指数表示法标识的。 1(L) 前置修饰符放在上面浮点格式字符前指示读取 double型的实数。 double 变量地址匹配scanf中的格式控制串“%lf”, float 变量地址匹配scanf中的格式控制串"%f",printf的格 式控制串"%f"可匹配 double 数据和float数据。
[例]输入浮点数 #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); }
//程序交互执行的结果// 键入3个float型数: 112233.333,445566.666,778899.123 112233,4.4455667e+005,778899.125000, 557799.992188 键入3个double型数: 显示键入的double型数与和: 1.122333e+005,445566.666000,778899,557799.999000
请打开 “第2章(3).ppt”