37
1 七七七七 printf 七七七七七七七七 scanf

七、输出函数 printf 八、输入格式转换函数 scanf

  • Upload
    dawson

  • View
    282

  • Download
    17

Embed Size (px)

DESCRIPTION

第二章 基本元素、类型和概念. 七、输出函数 printf 八、输入格式转换函数 scanf. 七、输出函数 printf printf 函数的格式为: printf (" 输出格式控制 " ,输出项 1 ,输出项 2,...); 输出格式控制由转义序列、格式转换说明符和普通字符 构成 , 格式转换说明符由“ %” 和格式字符组成,如 "%d,%f“ 中的 d,f 是格式字符。 它们结合在一起指定内存数据的输出格式。普通字符是 原样输出的字符。 如: printf ( "Sum is %d,\n", sum) 中的 Sum 以及逗号是普通字符。 - PowerPoint PPT Presentation

Citation preview

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' : tru

ncation 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,123

4

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 是一个十进制数字, d

dd

是三个十进制数构成的组合, iiii 是一个或多个十进制数,缺

省的数字个数或精度为 6 ; s 是正号 + 或负号 - 。方括号 [ ] 表示可省略的项。格

式字符 e 和 E 等价,差别只是大小写不同。 一般指数部分 Esddd 占五位字符宽度。

20

(3) %g 或 %G

以 %f 或 %e 格式更紧凑地转换有符号的浮点数,如果转

换的结果为指数形式后指数值小于 - 4 或大于等于预定的精度,用 %e 格式实现转换,否则通过 %f 格式转换。 双百分号 %% 用于显示百分号字符同时屏蔽掉紧跟其后的格式字符 ( 格式字符当作普通字符 ) 的转换作用。 没有宽度控制时,转换的数据相邻输出。

21

例如:printf ("%%e--%e, %%e--%e\n",123456789.0,5

e-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,44556

6.666000,778899,557799.999000

37