首页 > 代码库 > C语言格式化输出函数及使用禁区
C语言格式化输出函数及使用禁区
编译环境: Debian: 7.6 gcc: 4.7.2
一、格式化输出函数
C语言中设计到的标准格式化输出函数如下:
#include <stdio.h> int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); int sprintf(char *str, const char *format, ...); int snprintf(char *str, size_t size, const char *format, ...); #include <stdarg.h> int vprintf(const char *format, va_list ap); int vfprintf(FILE *stream, const char *format, va_list ap); int vsprintf(char *str, const char *format, va_list ap); int vsnprintf(char *str, size_t size, const char *format, va_list ap);
二、相互之间的关系
1、共同点:
在格式化字串的控制下,把数据输出到输出设备。格式化字串指定如何把后续的参数进行转化。如:
printf("%02x", 100); /* 输出是16进制 */ printf("%dx", 100); /* 输出是10进制 */
2、不同点:
按输出到的设备分:
printf() vprintf() | 输出至标准输出流stdout |
fprintf() vfprintf() | 输出至指定输出流 |
sprintf() snprintf() vsprintf() vsnprintf() | 输出至字串str |
按是否指定操作字节分:
snprintf() vsnprintf() | 写入至多size个字节(含‘\0‘)到dtr |
vprintf() vfprintf() vsprintf() vsnprintf() | 分别等同于:printf() fprintf() sprintf() snprintf() 区别是:它们都有va_list列表,一旦调用完毕,ap即成为“未定义”状态 |
3、返回值:
正常情况下,函数返回输出成功的字符个数(不含‘\0‘)。若出错,返回负值。
snprintf()和vsnprintf()输出字符个数不超过size字节(含‘\0‘),
如果size小于字符串的长度(不含‘\0‘),字符串会被截断,返回值是字符串的长度(不含‘\0‘),如下:
int len;
char str_buf[100];
len = snprintf(buf, 10, "%s$", "1234567890123");
// len: 13, buf: "1234567890"
如果size大于数据缓冲区长度,缓冲区长度个字串会被复制,返回值是字符串的长度(不含‘\0‘),如下:
char str_buf[5];
// len: 13, buf: "12345"
三、使用注意
1、在使用sprintf()和vsprintf()的时候,应确保数据大小不超出str缓冲区的大小,否则产生溢出,造成灾难。如果无法保证,应该选用snprintf()和vsnprintf()。
2、把字串加到原字串的后面,如下:
sprintf(buf, "%s append text", buf);
在我用的gcc中,这种使用如期运行;但是,在有的gcc版本中,结果并不正确。所以,不要这样做。
而且,标准中明确指出,调用sprintf(), snprintf(), vsprintf(),vsnprintf()函数,如果源、目标地址重叠,结果是未定义的(undefined).
3、像这样的代码printf(foo);往往会引入bug。因为如果foo中包含“%n”将引起printf()对内存的写入并造成安全漏洞。例如:
printf("%n"); // Segmentation fault
C语言格式化输出函数及使用禁区
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。