C/C++函数与算法速查宝典
上QQ阅读APP看书,第一时间看更新

2.2 格式化输入/输出函数

格式化输入/输出函数按照指定的格式(数据类型、对齐格式等)输出相应的数据。

2.2.1 printf函数──格式化输出数据

1.函数原型
int printf(const char *format[,argument]…); 
2.函数功能

printf函数的功能是在由format指定的格式控制下,将argument输出到屏幕上。

3.函数参数

(1)参数format:由格式说明和普通字符构成。其中,格式说明定义argument的显示格式,它以”%”开头,后面跟格式字符。格式字符前面还可以有其他修饰符,表示输出数据的宽度、精度等。参数format的格式如下。

%[flags][width][.precision][length]格式字符

格式说明的个数必须与参数argument的个数一致。格式字符及说明如表2-1所示。

表2-1 格式字符及说明

普通字符是按照原样输出的字符,如逗号、空格和换行符。

flags控制输出数据的对齐方式。flags及说明如表2-2所示。

表2-2 flags及说明

width控制数据输出的宽度。width及说明如表2-3所示。

表2-3 width及说明

precision表示单精度和双精度浮点数的小数点个数。precision及说明如表2-4所示。

表2-4 precision及说明

length表示整型数据是长整型还是短整型。length及说明如表2-5所示。

表2-5 length及说明

(2)参数argument:表示要格式化输出的数据,分别与格式字符对应。

4.函数的返回值

如果调用成功,则函数返回输出的字符个数;否则返回一个负数。

5.函数范例
/********************************************
*范例编号:02_06
*范例说明:格式化输出数据
*********************************************/
01    #include <stdio.h>
02    #include <stdlib.h>
03    void main()
04    {
05         printf (“整数: %d %ld\n”,2021, 6553500L);
06         printf (“以十、八、十六进制输出:%d %o %x\n”,-1,-1,-1);
07         printf (“以空格填充: %12d,以0填充:%012d\n”,2021,2021);
08         printf (“浮点数: %4.2f %+.0e %E \n”,9.825,9.825,9.825);
09         printf (“输出%: %f%%\n”,1.0/3);
10         printf (“字符: %c %c\n”,’A’,97);
11         printf (“字符串%-30s\n”, “this is a C program!”);
12         printf (“字符串%+30s\n”, “It is beautiful!”);
13         printf (“字符串% 30s\n”, “It is beautiful!”);
14         printf (“字符串:%s\n”, “How are you!”);
15         system (“pause”);
16    }

该函数范例的运行结果如图2-6所示。

图2-6 函数范例的运行结果

6.函数解析

(1)printf函数返回实际输出的字符个数(包括换行符)。例如,printf(“%d\n”,66)返回的是3,而不是2。

(2)printf函数中的格式控制字符包括普通字符和转义字符,如’\n’ ‘\r’ ‘\t’ ‘\f’。

(3)输出指针或地址时,应使用%p输出。

2.2.2 scanf函数──格式化输入数据

1.函数原型
int scanf(const char *format[,argument]); 
2.函数功能

scanf函数的功能是接受从键盘输入的数据,并将其转换为相应的格式。

3.函数参数

(1)参数format:由格式说明、空白字符与非空白字符构成。

格式说明:指示了参数 argument 的输入格式,它由%开头,后面跟格式字符,格式字符前也可以有其他修饰符。格式说明的一般格式如下。

%[*][width][modifiers]格式字符

格式字符及说明如表2-6所示。

表2-6 格式字符及说明

格式字符前面的修饰符及说明如表2-7所示。

表2-7 修饰符及说明

空白字符:可以使scanf函数忽略输入的一个或多个空白字符。空白字符可以是空格、制表符或换行符。实际上,scanf函数读入空白字符但是并不存储它们。

非空白字符:scanf函数读入并删除与该字符相同的字符。如果读入的字符与格式控制中的非空白字符不匹配,则停止读入。

(2)参数argument:一个地址列表,表示要格式化的输入数据的地址。

4.函数的返回值

如果调用成功,则函数返回读入数据的个数;如果读入出错,则返回与读入数据匹配的个数。

5.函数范例
/********************************************
*范例编号:02_07
*范例说明:格式化输入数据
*********************************************/
01    #include <stdio.h>
02    #include <stdlib.h>
03    void main()
04    {
05         char name[20];
06         float chinese,math,english,sum,average;
07         printf(“请输入你的姓名:”);
08         scanf(“%s”,name);  
09         printf(“请输入你的语文,数学,英语的成绩: “);
10         scanf(“%f,%f,%f”,&chinese,&math,&english);
11         printf(“你的姓名:%s.\n”,name);
12         printf(“语文 数学 英语\n”);
13         printf(“%.2f %.2f %.2f\n”,chinese,math,english);
14         sum=chinese+math+english;
15         average=sum/3.0;
16         printf(“%s的各门课成绩总分:%.2f,平均分:%.2f\n”,name,sum,average);
17         system(“pause”);
18    }

该函数范例的运行结果如图2-7所示。

图2-7 函数范例的运行结果

6.函数解析

(1)scanf函数的参数argument是变量的地址或字符串首地址,而不能是变量。地址列表中的变量名前需要加上&。

(2)一般情况下,回车键被认为是输入的结束。对于非字符型数据的输入,空格符、跳格符、回车键都可以被认为是输入的结束。

7.应用说明

使用*修饰符将忽略地址列表中的分隔符。例如,在下面的代码中,如果输入”20/30”,则忽略输入的”/”,将”20”赋给a,将”30”赋给b

scanf(“%d%*c%d”,&a,&b); 

在格式说明符中,除了格式字符还有其他字符。在输入数据时,应输入与这些格式说明符相同的字符。

scanf(“%d,%d”,&a,&b); 

例如,在上面的代码中,应该按照以下形式输入。

30,40

而下面的输入形式则是错误的。这是因为在格式说明中,两个数据以逗号分隔。

30 40
30:40

使用%c输入字符时,空格字符和转义字符都可以作为有效的字符输入。

scanf(“%c%c%c”,&a,&b,&c); 

例如,在上面的代码中,如果按照以下形式输入,则字符’x’将赋给a、’y’将赋给b、’z’将赋给c

x y z
8.注意事项

在输入数据时,不能指定输入数据的精度。例如,下面的输入形式是错误的。

scanf(“%6.3f”,&a); 

在使用scanf函数时,不要在格式说明中添加”\n”,这是很常见的错误。例如,下面的输入形式会造成输入错误。

scanf(“%d\n”,&a); 

2.2.3 sprintf函数──输出格式化数据到指定的数组中

1.函数原型
int sprintf(char *buffer,const char *format[,argument]); 
2.函数功能

sprintf函数的功能是将format指向的格式化数据输出到buffer指向的数组中。

3.函数参数

(1)参数buffer:存放格式化数据。

(2)参数format:格式说明,与printf函数的参数含义相同。

(3)参数argument:参数列表,与printf函数的参数含义相同。

4.函数的返回值

如果调用成功,则返回输出字符的个数(不包括字符串末尾的空字符);否则,返回负数。

5.函数范例
/********************************************
*范例编号:02_08
*范例说明:输出格式化数据到指定的数组中
*********************************************/
01    #include <stdio.h>
02    #include <stdlib.h>
03    void main() 
04    { 
05         int i,offset=0; 
06         char str[40]; 
07         for(i = 0; i < 10; i++) 
08              offset+=sprintf(str+offset,”%d,”,rand()%100); 
09         str[offset-1]=’\n’; 
10         printf(“产生的随机数分别是:\n%s”,str); 
11         system(“pause”);
12    }

该函数范例的运行结果如图2-8所示。

图2-8 函数范例的运行结果

6.函数解析

(1)printf函数与sprintf函数的区别:printf函数输出格式化数据到屏幕上,而sprintf函数输出格式化数据到指定的数组中。

(2)sprintf函数的返回值是输出字符的个数。

7.应用说明

利用sprintf函数的返回值可以将连续多个字符串输出到一个数组中。

2.2.4 sscanf函数──从字符串读取格式化数据

1.函数原型
int sscanf(char *buffer,const char *format[,argument]); 
2.函数功能

sscanf函数的功能是从buffer指向的字符串中读取format指定格式的数据,存储到argument中。sscanf函数的功能与scanf函数的类似。

3.函数参数

(1)参数buffer:存放用来读取的源数据。

(2)参数format:格式说明,与scanf函数的参数类似。

(3)参数argument:地址列表,与scanf函数的参数类似。

4.函数的返回值

如果调用成功,则返回输入数据的项数;否则,返回EOF。

5.函数范例
/********************************************
*范例编号:02_09
*范例说明:从字符串读取格式化数据
*********************************************/
01    #include <stdio.h>
02    #include <stdlib.h>
03    void main()
04    {
05         char str[]=”3 plus 5 equals 8!”;
06         int a,b,c;
07         printf(“%s\n”,str);
08         sscanf(str,”%d %*s %d %*s %d”,&a,&b,&c);
09         printf(“%d+%d=%d\n”,a,b,c);
10         system(“pause”);
11    }

该函数范例的运行结果如图2-9所示。

图2-9 函数范例的运行结果

6.函数解析

如果格式字符是%s,则从指定的源字符串中读取字符序列,遇到空格符、跳格符或换行符则停止读取。例如,在下面的代码中,%s读取字符串”Tom live Beijing”,%*s忽略空格符,%d读取”10”到year中。

01   char s[]=”Tom live Beijing 10 years”;
02   char str[20]; 
03   int year; 
04   sscanf (s,”%s %*s %d”,str,&year); 

2.2.5 vprintf函数──在屏幕上输出格式化变长参数列表

1.函数原型
int vprintf(const char *format,va_list arg_ptr); 
2.函数功能

vprintf函数的功能是在屏幕上输出格式化变长参数列表中的数据。

3.函数参数

(1)参数format:要输出的文本,可以包含格式字符,格式化字符由变长参数指针指示。与printf函数中的参数format含义相同。

(2)参数arg_ptr:变长参数列表对象。其实它是一个指向参数列表的指针。va_list类型在stdarg.h中定义。

4.函数的返回值

如果调用成功,则返回输出的字符个数;否则,返回负数。

5.函数范例
/********************************************
*范例编号:02_10
*范例说明:在屏幕上输出格式化变长参数列表
*********************************************/
01    #include <stdio.h>
02    #include <stdarg.h>
03    #include <stdlib.h>
04    void PrintFormatted(char *format, ...)
05    {
06         va_list args;
07         va_start(args, format);
08         vprintf(format, args);
09         va_end(args);
10    }
11    void main()
12    {
13         PrintFormatted(“Welcome to use %s.\n”,”Visual Studio 2019”);
14         PrintFormatted(“The 120th anniversary of %s will be celebrated 
15                        in %d.\n”,”Northwest University”,2022);
16         PrintFormatted(“The %dth and %dth anniversary of %s and %s will be celebrated
17              in %d.\n”,120,100,”Nanjing University”,”Southeast University”,2022);
18         system(“pause”);
19    }

该函数范例的运行结果如图2-10所示。

图2-10 函数范例的运行结果

6.函数解析

(1)参数arg_ptr指向要格式化的变长参数。

(2)在调用vprintf函数前,需要先调用va_start函数初始化的va_list类型的指针;在调用结束后,需要使用va_end函数释放的va_list类型的变量。

2.2.6 vscanf函数──读取从键盘输入的格式化数据

1.函数原型
int vscanf(const char *format,va_list arg);
2.函数功能

vscanf函数读取从键盘输入的格式化数据。

3.函数参数

(1)参数format:格式说明符,与scanf函数的参数含义相同。

(2)参数arg:变长参数对象,指向接受数据的变量地址列表。

4.函数的返回值

如果调用成功,则函数返回输入数据的项数;否则,返回EOF。

5.函数范例
/********************************************
*范例编号:02_11
*范例说明:读取从键盘输入的格式化数据
*********************************************/
01    #include <stdio.h>
02    #include <stdarg.h> 
03    int InputFormatted(char *fmt, ...) 
04    { 
05         va_list argptr; 
06         va_start(argptr, fmt); 
07         vscanf(fmt, argptr);
08         va_end(argptr); 
09    } 
10    void main()
11    { 
12         long int no;
13         int age; 
14         float score; 
15         printf(“Please Input no,age,score(e.g.1001,23,89.5):\n”);
16         InputFormatted(“%ld,%d,%f”,&no,&age,&score);
17         printf(“%ld %d %f\n”, no, age, score);
18    }

该函数范例的运行结果如图2-11所示。

图2-11 函数范例的运行结果

6.函数解析

vscanf函数的作用与scanf函数的类似,不同之处在于vscanf函数由变长参数列表指针接受输入的数据,而scanf函数则由地址列表接受输入的数据。