您的位置:首页 > 其它

C IO(格式化输入输出)

2013-09-25 10:00 169 查看
INPUT


intprintf(constchar*format,...);

格式化输出格式如下:

%[flags][width][.precision][length]specifier

一些比较实用的标记:

flags:-左对齐,默认为右对齐

+显示正负号,默认只显示负号

#显示前缀标记,如和0x结合使用,输出会在数值前面加上0x

0当指定输出width时,默认以空格填充,0指示以0填充



width:指定输出的有效位。


specifiers

lengthdiuoxXfFeEgGaAcspn
(none)intunsignedintdoubleintchar*void*int*
hhsignedcharunsignedcharsignedchar*
hshortintunsignedshortintshortint*
llongintunsignedlongintwint_twchar_t*longint*
lllonglongintunsignedlonglongintlonglongint*
jintmax_tuintmax_tintmax_t*
zsize_tsize_tsize_t*
tptrdiff_tptrdiff_tptrdiff_t*
Llongdouble


specifier:p接收一个指针,并打印其地址

一个注意的地方:

由于整数和浮点数存储机制不同,以下调用会输出错误的值:

printf("%d",23.0);//输出为0




intfprintf(FILE*stream,constchar*format,...)

和printf相似,只不过输出有stdout变成了流


intsprintf(char*str,constchar*format,...);


intsnprintf(char*s,size_tn,constchar*format,...);//c11added

输出定向为字符串,与snprintf相比,sprintf需要给str预留足够的空间,建议使用snprintf


intvprintf(constchar*format,va_listarg);



输出va_list类型的参数到stdout,与printf的原理相同,

讲一下什么是参数列表va_list(下面属于扯淡)

如printf的原型intprintf(constchar*format,...);

有时候我们编写函数的时候,有可能你事先并不知道需要传递传递多少个参数,C允许我们用...代表未知个数的参数,
它有可能是空的,或者1个或者多个参数。那么我们怎么知道到底有多少个参数,每个参数的类型是什么,答案是格式化字符串。
就是我们平时使用的诸如“%d%f%c”,从字符串中,我们知道,...应该总共有三个参数,一个int,一个float,一个char
当然也有可能还有第三个或者更多参数,也或者,第一个根本不是int,这属于使用者传参错误的情况,应该避免。
标准库提供了方法获取每个参数的方法,但是其参数个数及类型还是需要你去分析。
下面是个例子:


#include<stdio.h>
/*printf*/[/code]
#include<stdarg.h>/*va_list,va_start,va_arg,va_end*/

intFindMax(intn,...)
{
inti,val,largest;
va_listvl;
va_start(vl,n);
largest=va_arg(vl,int);
for(i=1;i<n;i++)
{
val=va_arg(vl,int);
largest=(largest>val)?largest:val;
}
va_end(vl);
returnlargest;
}

intmain()
{
intm;
m=FindMax(7,702,422,631,834,892,104,772);
printf("Thelargestvalueis:%d\n",m);
return0;
}

上面
FindMax第一个参数是7,简化了从formatstring中分析参数个数的步骤,而参数全部为int简化了分析参数类型。
[/code]

更近一步,看看va_list和va_startva_end是个什么东东,

下面是这些东东在x86下面的一个实现



typedefchar*va_list;

#define_INTSIZEOF(n)\

((sizeof(n)+sizeof(int)-1)&~(sizeof(int)-1))

#defineva_start(ap,v)(ap=(va_list)&v+_INTSIZEOF(v))

#defineva_arg(ap,t)\

(*(t*)((ap+=_INTSIZEOF(t))-_INTSIZEOF(t)))

#defineva_end(ap)(ap=(va_list)0)



_INTSIZEOF是将n以int对齐的算式,x86以int对齐。


回到程序,调用va_start(args,format)后,则args指向了format之后的地址,va_start相当于初始化args,

va_arg从args中取出t类型的数据。代码比较简单,

va_end将args赋为NULL。



intvfprintf(FILE*stream,constchar*format,va_listarg);

与vprintf的区别是输出为文件。


intvsprintf(char*s,constchar*format,va_listarg);

输出到字符串,s需要有足够的大小。

intvsnprintf(char*s,size_tn,constchar*format,va_listarg);//c11


vsprintf的安全版


INPUT


intscanf(constchar*format,...);

从stdin读取格式化输入。需要注意的是scanf以键盘\n结束输入,以空格分割token。



intfscanf(FILE*stream,constchar*format,...);

从文件中获取格式化字符串。


intsscanf(constchar*s,constchar*format,...);


从字符串中获取。



intvscanf(constchar*format,va_listarg);//c11


intvsscanf(constchar*s,constchar*format,va_listarg);//c11


intvfscanf(FILE*stream,constchar*format,va_listarg);/c11

作用类似,只不过格式化数据来源不同,分别为stdin,字符串,文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: