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. Linux中main是如何执行的

    Linux中main是如何执行的 这是一个看似简单的问题,但是要从Linux底层一点点研究问题比较多.找到了一遍研究这个问题的文章,但可能比较老了,还是在x86机器上进行的测试. 原文链接 开始 问题 ...

  2. PyCharm 如何安装python第三方库及插件

    一.如何安装python第三方库: 1.有一个专门可下载安装第三方库的网址: http://www.lfd.uci.edu/~gohlke/pythonlibs/ Ctrl+f 搜索要下载的第三方库, ...

  3. HDU 4267 A Simple Problem with Integers(树状数组区间更新)

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. 楼梯T-SQL:超越基础6级:使用CASE表达式和IIF函数

     从他的楼梯到T-SQL DML,Gregory Larsen涵盖了更多的高级方面的T-SQL语言,如子查询. 有时您需要编写一个可以根据另一个表达式的评估返回不同的TSQL表达式的单个TSQL语句. ...

  5. 初入红尘——在安联IT实习的一点感受(未完......)

    文章很短,只有800字. 从踏进安联的大门开始,我便入了红尘. 安联的迎客之道 “花径不曾缘客扫,蓬门今始为君开.”我的第一个贵人就是前台的美君姐.由于路况不熟,所以我没把握好时间,到的时候比约定的面 ...

  6. Hive中常用的查询命令

    日志数据的统计处理在这里反倒没有什么特别之处,就是一些 SQL 语句而已,也没有什么高深的技巧,不过还是列举一些语句示例,以示 hive 处理数据的方便之处,并展示 hive 的一些用法. a)    ...

  7. linux系统下解决getch()输入数值不回显示

    在linux系统下开发C 程序却会遇到系统不支持conio.h头文件,无法使用getch()不回显函数.下面就演示如何构建函数实现数值输入不回显. #include <stdio.h> # ...

  8. Java设计模式相关面试

    1.接口是什么?为什么要使用接口而不是直接使用具体类? 接口用于定义 API.它定义了类必须得遵循的规则.同时,它提供了一种抽象,因为客户端只使用接口,这样可以有多重实现,如 List 接口,你可以使 ...

  9. windows中更换Jdk版本不生效

    本机已经安装了jdk1.7,而比较早期的项目需要依赖jdk1.6,于是同时在本机安装了jdk1.6和jdk1.7. 安装jdk1.6前,执行java -version得到 C:\Users\liuxi ...

  10. C#中简单的this与get的用法(string,decimal)

    代码 namespace First{publicpartialclass Form1 : Form{public Form1(){InitializeComponent();} privatevoi ...