snprintf()函数用于将格式化的数据写入字符串,其原型为:

    int snprintf(char *str, int n, char * format [, argument, ...]);
  • str为要写入的目标字符串;
  • n为能写入的字符的最大数目,超过n会被截断,包括'\0'符,所以能最大写入的其实是n-1个字符;
  • format为格式化字符串,使用方式与printf()函数相同;
  • argument为变量,可为多个,取决于format,这里的使用方式与printf相同。
  • 成功则返回参数str 字符串长度(不包括“\0”),失败则返回-1,错误原因存于errno 中。

snprintf()可以认为是sprintf()的升级版,比sprintf()多了一个参数,可以控制要写入的字符串的长度,更加安全,不会造成str的溢出。

不过snprintf也不是尽善尽美的,也有陷阱,当要写入的argument的长度大于str的长度时,返回值不是str的长度,而是argument的长度

#include <stdio.h>
#include <stdlib.h> int main(void)
{
int len;
char str[5];
len = snprintf(str, sizeof(str), "%s", "ABCDEFGH");
printf("str:%s, len:%d.\n", str, len); return 0;
}

输出结果:

str:ABCD, len:8.

返回的长度是8而不是4,不注意的话,下边的使用可能有问题。所以,使用后,下边最好再判断一下len的长度是否超过了size。

其实可以自己封装一个my_snprintf的

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> int my_snprintf(char *dst, int size, char *fmt, ...)
{
int len;
va_list argp;
va_start(argp, fmt);
len = vsnprintf(dst, size, fmt, argp);
len = len > size - 1 ? size - 1 : len;
va_end(argp); return len;
} int main(void)
{
char str[8];
int len; len = my_snprintf(str, sizeof(str), "A:%d:%s", 1, "ABCDEFGH");
printf("str:%s, len:%d\n", str, len); return 0;
}

输出:

str:A:1:ABC, len:7

snprintf 返回值陷阱 重新封装的更多相关文章

  1. snprintf()返回值的陷阱

    int snprintf(char *restrict buf, size_t n, const char * restrict  format, ...); 函数说明:最多从源串中拷贝n-1个字符到 ...

  2. snprintf 返回值

    在平时写代码的过程中,我一个推荐带有n系列的字符串函数,如 strcat ->strncat sprintf->snprintf 我们有类似的一个函数 void dump_kid(std: ...

  3. VB6 让程序结束后带有返回值

    第三方命令行程序运行完之后,批处理中可以随时通过errorlevel变量收取运行结果.而VB写的控制台程序却没有提供这样的功能.关于让控制台程序返回值的教程是本博客独家放出. 返回值,其实也就是进程的 ...

  4. 编写JsonResult封装JSON返回值(模板参阅)

    编写JsonResult封装JSON返回值 package cn.tedu.note.util; import java.io.Serializable; import cn.tedu.note.se ...

  5. spring boot 接口返回值封装

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  6. C#中返回值封装

    在平时开发过程中常常需要取一个方法的返回值,BOSS写了一个返回值类,做个练习以备不时之需: 返回值支持泛型和非泛型 先贴上代码: 非泛型返回值类: using System; using Syste ...

  7. [Python陷阱]os.system调用shell脚本获取返回值

    当前有shell个脚本/tmp/test.sh,内容如下: #!/bin/bashexit 11 使用Python的os.system调用,获取返回值是: >>> ret=os.sy ...

  8. C#:struct的陷阱:无法修改“xxx”的返回值,因为它不是变量

    示例代码如下: public struct SpiderResult { public string robotName; public string RobotName { get { return ...

  9. C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解  ...

随机推荐

  1. Java求555 555的约数中最大的三位数。

    package org.llh.test; /** * 求555 555的约数中最大的三位数 * @author llh * */ public class Car { //整数j除以整数i(i≠0) ...

  2. 在为知笔记中使用Markdown和思维导图

    为知笔记Wiz是一款很好的网摘和笔记工具,作为为知的忠实用户,我在为知收费后第一时间就购买了两年的授权,毕竟这么多年积累的资料都在为知上,我也习惯了使用Wiz来做些工作相关的笔记.为知笔记自带Mark ...

  3. 万年历java

    public void showTime(){/*万年历 :  1900年1月20号是星期几?1月1号是星期一1月8号是星期一1月15号是星期一1%7 = 18%7 = 115%7 = 1★: 1. ...

  4. 分享:苹果APP更新上架被拒的另一种理由(Safety - Objectionable Content)

    这两个星期,本来想和大伙分享:写IT连创业系列运营篇. 但时间飞过,仍只是写了开头,一直很忙,没能完往下写. 今天就动手写点其它内容,哈哈,免的和小伙伴太陌生〜〜〜 前几天更新了:IT恋和IT连的版本 ...

  5. KICKSTART无人值守安装 - (字符界面操作)

    kickstart 部署 1.1 kickstart简介说明 1.1.1 pxe工作过程(图) 1.1.2 kickstart具体过程(图) 1.2 kickstart无人值守部署 1.2.1 系统环 ...

  6. Python之numpy模块array简短学习

    1.简介 Python的lists是非常的灵活以及易于使用.但是在处理科学计算相关大数量的时候,有点显得捉襟见肘了. Numpy提供一个强大的N维数组对象(ndarray),包含一些列同类型的元素,这 ...

  7. 深入学习JS执行--创建执行上下文(变量对象,作用域链,this)

    一.介绍 本篇继上一篇深入理解js执行--单线程的JS,这次我们来深入了解js执行过程中的执行上下文. 本篇涉及到的名词:预执行,执行上下文,变量对象,活动对象,作用域链,this等 二.预执行 在上 ...

  8. Python——正则表达式特殊符号及用法

    由于正则表达式的内容比较多,所以单独写成一系列文章,主要内容是根据小甲鱼所讲的内容综合一下正则表达式的笔记. 贴上小甲鱼的<Python3 如何优雅地使用正则表达式>系列可观看的博客地址: ...

  9. MyBatis物理分页的代码实现

    一.分页 MyBatis有两种分页方法:内存分页,也就是假分页,本质是查出所有的数据然后根据游标的方式,截取需要的记录,如果数据量大,执行效率低,可能造成内存溢出.物理分页,就是数据库本身提供了分页方 ...

  10. css中的float和position

    1.float <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...