格式化输出是由5个printf 函数来处理的
#include <stdio.h>
int printf(const char *restrict format, ...);
int fprintf(FILE *restrict fp, const char *restrict format, ...);
int dprintf(int fd, const char *restrict format, ...);
int sprintf(char *restrict buf, const char *restrict format, ...);
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
printf将格式化数据写到标准输出
fprintf写至指定的流
dprintf写至指定的文件描述符
sprintf将格式化字符写入buf中。 sprintf在该字符串的文段自动加上一个NULL,但该字节不包括在返回值中
注意,sprintf函数可能会造成有buf指向的缓冲区的溢出。
为了解决缓冲区溢出安全隐患,引入了snprintf函数,超过缓冲区尾端写的所有字符都被丢弃。与sprintf相同,该返回值不包括结尾的null字节。
printf的变体: 可变参数(...)替换成arg
#include <stdarg.h>
#include <stdio.h>
int vprintf(const char *restrict format, va_list arg);
int vfprintf(FILE *restrict fp, const char *restrict format, va_list arg);
int vdprintf(int fd, const char *restrict format, va_list arg);
int vsprintf(char *restrict buf, const char *restrict format, va_list arg);
int vsnprintf(char *restrict buf, size_t n, const char *restrict format, va_list arg);
格式化输入,3个scanf函数
#include <stdio.h>
int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(char *restrict buf, const char *restrict format, ...);
可变参数
#include <stdarg.h>
int VarArgFunc(int dwFixedArg, ...){ //以固定参数的地址为起点依次确定各变参的内存起始地址
va_list pArgs = NULL; //定义va_list类型的指针pArgs,用于存储参数地址
va_start(pArgs, dwFixedArg); //初始化pArgs指针,**使其指向第一个可变参数。该宏第二个参数是变参列表的前一个参数,即最后一个固定参数**
int dwVarArg = va_arg(pArgs, int); //该宏返回变参列表中的当前变参值并使pArgs指向列表中的下个变参。该宏第二个参数是要返回的当前变参类型
//若函数有多个可变参数,则依次调用va_arg宏获取各个变参
va_end(pArgs); //将指针pArgs置为无效,结束变参的获取
/* Code Block using variable arguments */
}
//可在头文件中声明函数为extern int VarArgFunc(int dwFixedArg, ...);,调用时用VarArgFunc(FixedArg, VarArg);
stdarg.h头文件内变参宏定义如下:
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n)+sizeof(int)-1) & ~(sizeof(int)-1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap, type) ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )
#define va_end(ap) ( ap = (va_list)0 )
示例:
#include <stdio.h>
#include <stdarg.h>
double average(int num,...)
{
va_list valist;
double sum = 0.0;
int i;
/* 为 num 个参数初始化 valist */
va_start(valist, num);
/* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++)
{
sum += va_arg(valist, int);
}
/* 清理为 valist 保留的内存 */
va_end(valist);
return sum/num;
}
int main()
{
printf("Average of 2, 3, 4, 5 = %f
", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f
", average(3, 5,10,15));
}
习题:
下面的代码在一些机器上运行正确,而在另一些机器上运行时出错,解释问题所在
#include <stdio.h>
int main(void)
{
char c;
while((c=getchar())!=EOF)
putchar(c);
}
答案:
getchar返回值为int型,当系统的char型为有符号型时能正常运行,当系统的char为无符号型时,EOF 不再是-1, 运行死循环
int getchar(void);