博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
snprintf 返回值陷阱 重新封装
阅读量:4982 次
发布时间:2019-06-12

本文共 1300 字,大约阅读时间需要 4 分钟。

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 
#include
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 
#include
#include
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

转载于:https://www.cnblogs.com/shenlinken/p/8046341.html

你可能感兴趣的文章
架构必备词汇
查看>>
SublimeText快捷键操作
查看>>
Python开发 基礎知識 (未完代補)
查看>>
监听器的使用,以及实现, 测试
查看>>
java基础二 分支循环
查看>>
python--002--数据类型(list、tuple)
查看>>
把近期的小错误整理一下
查看>>
动态规划 —— 背包问题一 专项研究学习
查看>>
51nod 1571 最近等对 | 线段树 离线
查看>>
关于parseInt的看法
查看>>
从用户端到后台系统,严选分销教会我这些事
查看>>
数据分析融入至BI工具的新思路
查看>>
c#必会知识点
查看>>
网页使用MD5加密
查看>>
JS 基础
查看>>
HBase shell 中的十六进制数值表示
查看>>
Python3 中 configparser 模块解析配置的用法详解
查看>>
新手android环境搭建、debug调试及各种插件安装__图文全解
查看>>
未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序 win2008R2 X64 IIS7.5
查看>>
Diffuse贴图+Lightmap+Ambient
查看>>