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. 原生JS实现Ajax及Ajax的跨域请求

      前  言          如今,从事前端方面的程序猿们,如果,不懂一些前后台的数据交互方面的知识的话,估计都不太好意思说自己是程序猿.当然,如今有着许多的框架,都有相对应的前后台数据交互的方法. ...

  2. Lua如何管理”package”

    Lua如何管理"package" 方式一: 私有方法和变量都需要显式定义为local类型的,这很容易造成错误.一旦不小心漏写,就又将方法定义为全局的了. "package ...

  3. C. New Year and Rating

    C. New Year and Rating time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. linux-more

    more 这个命令可以用来分页查看大篇幅的文件内容非常有效 命令参数: -num  : 这里的num 是一个数字,用来指定分页显示时每页的行数 +num  : 指定从文件的第几行num开始显示 ... ...

  5. Remove Untagged Images From Docker

    I've been playing around a lot with docker. It's awesome, and it creates a whole new world of possib ...

  6. MS-SQL 错误: The offset specified in a OFFSET clause may not be negative

    Example 1 : (Fetch clause must be greater than zero) USE AdventureWorks2012 GO SELECT * FROM [HumanR ...

  7. PHP代码审计---基础

    PHP伪协议 PHP伪协议事实上是其支持的协议与封装协议,支持的种类有以下12种. * file:// - 访问本地文件系统 * http:// - 访问 HTTP(s) 网址 * ftp:// - ...

  8. sql分区文件删不的可能解决方法

    删除数据库分区的时候报错如下: ALTER DATABASE [ITMP2] remove FILE F20170427Msg 5042, Level 16, State 1, Line 1The f ...

  9. js中的break,continue和return到底怎么用?

    为什么要说个?好像很简单,但是我也会迷糊,不懂有时候为什么要用return,然而break和continue也经常和他放在一起. 所以就一起来说一说,这三个看起来很简单,却常常会出错的关键词的具体用法 ...

  10. 很考验人的java内存加载面试题

    源代码如下,求结果 public class MemoryAnalyse { public static int k = 0; public static MemoryAnalyse t1 = new ...