snprintf()函数使用方法

众所周知,sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf.

自从snprintf代替了sprintf,相信大家对snprintf的使用都不会少,函数定义如下:

int snprintf(char*str, size_t size,constchar*format, ...);

函数说明:

最多从源串中拷贝size-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为size的话,将不会溢出。

函数返回值:

若成功则返回欲写入的字符串长度,若出错则返回负值。

但是大家在使用snprintf的时候是否真的清楚参数里size的意思呢?看下面的例子:

假设我想将一个char类型的变量打印成2位的10进制,我应该怎么写呢?

char a=‘a‘;
char str[20];
snprintf(str,2,"%02d",a);

上面这么写,对不对呢,错了。

1) 2不应该是2,应该是3.
2) 也不建议直接写3,应该写sizeof(str)

所以建议的写法是:

char a=‘a‘;
char str[3];//再大点也没有问题
snprintf(str,sizeof(str),"%02d",a);

解释如下:

size是限定最终生成的dest的字符数,最多拷贝size-1个字符; 一般情况下size会取sizeof(dest),这是为了dst不溢出.

在snprintf(dest, size, "str: %s\n", src)中如果size-1大于等于"str: %s\n"的长度,则把"str: %s\n"都拷贝到dst; 如果size-1小于"str: %s\n"的长度,则从"str: %s\n"拷贝size-1长度的字符串到dst,并且末尾置\0.

就是说,拷贝的长度是size-1和源字符串长度的最小值;

对于返回值,需要注意的是snprintf的返回值是欲写入的字符串(即源字符串)长度,而不是实际写入的字符串度。如:

char test[8];

int ret= snprintf(test,5,"1234567890");

printf("%d|%s\n",ret,test);

运行结果为:

10|1234

最后,注意这个函数在linux和windows下是不同的linux下用的是snprintf(),而windows下用的是_snprintf();

原文地址:https://www.cnblogs.com/LifeoFHanLiu/p/10797588.html

时间: 2024-08-28 20:31:53

snprintf()函数使用方法的相关文章

【转】snprintf()函数使用方法

众所周知,sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf. 注:sprintf()函数:int sprintf( char *buffer, const char *format, [ argument] … );返回的是实际写入buffer的长度 自从snprintf代替了sprintf,相信大家对snprintf的使用不会少,函数定义如下: int snprintf(char* dest_str,size_t size,const char*

[C/C++基础] C语言常用函数sprintf和snprintf的使用方法

Sprintf 函数声明:int sprintf(char *buffer, const char *format [, argument1, argument2, -]) 用途:将一段数据写入以地址buffer开始的字符串缓冲区 所属库文件: <stdio.h> 参数:(1)buffer,将要写入数据的起始地址:(2)format,写入数据的格式:(3)argument:要写的数据,可以是任何格式的. 返回值:实际写入的字符串长度 说明:此函数需要注意缓冲区buffer溢出,要为写入的arg

unity中三种调用其他脚本函数的方法

第一种,被调用脚本函数为static类型,调用时直接用  脚本名.函数名().很不实用-- 第二种,GameObject.Find("脚本所在物体名").SendMessage("函数名");  此种方法可以调用public和private类型函数 第三种,GameObject.Find("脚本所在物体名").GetComponent<脚本名>().函数名();此种方法只可以调用public类型函数 unity中三种调用其他脚本函数的

matlab中同一文件定义子函数的方法

在matlab中一个.m文件中可以有多个的子函数,但仅能有一个主函数,并且M文件名必须和主函数相同在一个m文件中通常有两种定义子函数的方法: 1.嵌套定义 myfunc1会和主函数共享变量名.这种情况下,使用相同的变量名,如果不是故意为之,就不合适了.function mainFunc(... a = myfunc1();...function myfunc1()...end end2. 非嵌套定义function mainFunc()...a = myfunc1();...end functi

【C语言天天练(十三)】printf、fprintf、sprintf和snprintf函数

#include <stdio.h> int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); int sprintf(char *str, const char *format, ...); int snprintf(char *str, size_t size, const char *format, ...); printf是标准的输出函数. fprintf传送格式化输

boost在lambda表达式中调用占位符参数的成员函数的方法

boost中提供了lambda表达式的用法,但是lambda表达式的功能还不是很强大,在其中只能对lambda的占位符参数_1等使用最基本的操作符,如+-*/,可是很多时候如果传入的占位符参数是一个对象指针的话,我们可能想要调用这个类的成员函数. 我在开发中遇到了这个问题,需要在stl的算法中传入一个函数来调用对象的比较函数,因为感觉这样太麻烦,还需要重新定义一个函数,所以想起了lambda表达式,c++11的lambda表达式我倒是没试过,可是受项目开发环境所限,只能选择boost.但是我用的

函数与方法对比

对象方法: (1)对象方法的实现只能写在@[email protected]中,对象方法的声明只能写在 @[email protected]中间 (2)对象方法都以-号开头,类方法都以+号开头 (3)对象方法只能由对象来调用,类方法只能由类来调用,不能当做函数一样调用 (4)函数属于整个文件,可以写在文件中的任何位置,包括@[email protected]中,但写在 @[email protected]会无法识别,函数的声明可以在main函数内部也可以在main函数外部. (5)对象方法归类\

李洪强iOS开发之OC[017]函数和方法的区别

// //  main.m //  15 - 函数和对象的方法的区别 // //  Created by vic fan on 16/7/12. //  Copyright © 2016年 李洪强. All rights reserved. // 函数和对象方法的区别 对象方法: - (void)run; #import <Foundation/Foundation.h> @interface Person : NSObject{ @public //定义实例变量 NSString *_nam

String类中的一些函数使用方法

最常用的就是Length()函数了,求字符串的长度 String s="";int i=s.length();i结果为0. 如果是String s=null;int i=s.length();编译没错.运行会报错 charAt()函数: charAt(int index)方法是一个能够用来检索特定索引下的字符的String实例的方法. charAt()方法返回指定索引位置的char值.索引范围为0~length()-1. 如: str.charAt(0)检索str中的第一个字符,str