代码改变世界

格式化字符串函数sprintf

2014-12-14 02:48  rangers  阅读(1448)  评论(0编辑  收藏  举报

sprintf、snprintf相关函数的主要功能是把格式化的数据写入某个字符串。如最常见的应用是将整数或浮点数转换为字符串。

1、sprintf

将格式化的数据写入字符串,并自动在末尾加上一个空字符'\0'.

原型:

int sprintf ( char * str, const char * format, ... );

 str: 要写入的字符串缓冲区地址

 format: 格式化数据

 返回:执行成功时,返回写入到字符个数。

const int MAX_LEN = 5;
char buf[MAX_LEN];
int ret = sprintf(buf,"%dabc",2);
cout << "Write character number" << ret << endl;
cout << buf << endl;

output:

Write character number:4
2abc

注意:使用sprintf时要一定要确保字符串缓冲区足够大,当要写入的数据长度大于缓冲区的容量时,将导致程序异常。

2、snprintf

原型:

int snprintf ( char * s, size_t n, const char * format, ... );

该函数比sprintf多一个size_t n参数,该参数指出了字符串缓冲区的最大容量。如果写入的字符个数 > n - 1,超过的部分将会被截断,即最多写入n-1个字符,并自动添加'\0'。该函数返回欲写入的字符串长度。

如下:

const int MAX_LEN = 5;
char buf[MAX_LEN];
int ret = snprintf(buf,MAX_LEN,"%dABCDEF",2);

最终输出结果:2ABC

注:该函数只存在与linux/Unix平台,windows下并没有该函数,但存在类似函数_snprintf等。

 

以下函数存在于windows平台:

3、sprintf_s

sprintf所谓的安全版本。

原型:

int sprintf_s(
    char *buffer,
    size_t sizeOfBuffer,
    const char *format [,
    argument] ... 
   );

buffer: 缓冲区地址

sizeofBuffer: 缓冲的最大容量

format:格式化数据

返回:执行成功时,返回写入的字符个数

msdn上描述如下:

if the buffer is too small for the text being printed then the buffer is set to an empty string and the invalid parameter handler is invoked.

如果写入的数据长度大于 sizeBuffer - 1 ,将会触发错误。

如在vs2010 Debug模式下:

const int MAX_LEN = 5;
char buf[MAX_LEN];
ret = sprintf_s(buf,sizeof(buf),"%dABCD",2);
cout << "Write character number:" << ret << endl;
cout << buf << endl;

会弹出如下错误提示:

 

4、_snprintf

int _snprintf(
    char *buffer,
    size_t count,
    const char *format [,
    argument] ... 
    );

 功能与snprintf类似,count表示最多能写入的字符个数, 执行成功时返回写入的字符个数,失败时返回-1;

但要注意,msdn如下描述:

If len < count, len characters are stored in buffer, a null-terminator is appended, and len is returned.

If len = count, len characters are stored in buffer, no null-terminator is appended, and len is returned.

If len > count, count characters are stored in buffer, no null-terminator is appended, and a negative value is returned.

所以使用_snprintf后有可能生成的字符串没有以空字符结尾,所以在使用时一定要检查返回值

一种安全的做法是:

char buff2[MAX_LEN] = {0};
ret = _snprintf(buff2,sizeof(buff2) - 1,"%dCDEF",2);
if (ret < 0)
{
  cout << "Warning:string will be truncated" << endl;
}

 

5、_snprintf_s

_snprintf的安全版本,所谓的安全就是 _s类函数在字符串超出缓冲区的容量大小时,会调用invalid parameter handler处理程序,即弹出错误提示框。

原型:

int _snprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format [,
   argument] ... 
);

sizeofBuffer: 缓冲区的最大容量

count: 最多能写入的字符个数

 

ret = _snprintf_s(buf,sizeof(buf),sizeof(buf) - 1,"%d1234",2);
cout << "_snprintf_s ret:" << ret << endl;
cout << buf << endl;