snprintf(3) - safe sprintf
#include <slack/std.h>
#ifndef HAVE_SNPRINTF
#include <slack/snprintf.h>
#endif
int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list args);
Safe version of sprintf(3) of that doesn't suffer from buffer overruns.
int snprintf(char *str, size_t size, const char *format, ...)
Writes output to the string str
, under control of the format string format
, that specifies how subsequent arguments are converted for output. It is similar to sprintf(3), except that size
specifies the maximum number of characters to produce. The trailing nul
character is counted towards this limit, so you must allocate at least size
characters for str
.
If size
is zero, nothing is written and str
may be null
. Otherwise, output characters beyond the n-1
st are discarded rather than being written to str
, and a nul
character is written at the end of the characters actually written to str
. If copying takes place between objects that overlap, the behaviour is undefined.
On success, returns the number of characters that would have been written had size
been sufficiently large, not counting the terminating nul
character. Thus, the nul
-terminated output has been completely written if and only if the return value is nonnegative and less than size
. On error, returns -1
(i.e. encoding error).
Note that if your system already has snprintf(3) but this implementation was installed anyway, it's because the system implementation has a broken return value. Some older implementations (e.g. glibc-2.0) return -1
when the string is truncated rather than returning the number of characters that would have been written had size
been sufficiently large (not counting the terminating nul
character) as required by ISO/IEC 9899:1999(E).
int vsnprintf(char *str, size_t size, const char *format, va_list args)
Equivalent to snprintf(3) with the variable argument list specified directly as for vsprintf(3).
MT-Safe - provided that the locale is only set by the main thread before starting any other threads.
How long is a piece of string?
#include <slack/std.h>
#ifndef HAVE_SNPRINTF
#include <slack/snprintf.h>
#endif
int main(int ac, char **av)
{
char *str;
int len;
len = snprintf(NULL, 0, "%s %d", *av, ac);
printf("this string has length %d/n", len);
if (!(str = malloc((len + 1) * sizeof(char))))
return EXIT_FAILURE;
len = snprintf(str, len + 1, "%s %d", *av, ac);
printf("%s %d/n", str, len);
free(str);
return EXIT_SUCCESS;
}
Check if truncation occurred:
#include <slack/std.h>
#ifndef HAVE_SNPRINTF
#include <slack/snprintf.h>
#endif
int main()
{
char str[16];
int len;
len = snprintf(str, 16, "%s %d", "hello world", 1000);
printf("%s/n", str);
if (len >= 16)
printf("length truncated (from %d)/n", len);
return EXIT_SUCCESS;
}
Allocate memory only when needed to prevent truncation:
#include <slack/std.h>
#ifndef HAVE_SNPRINTF
#include <slack/snprintf.h>
#endif
int main(int ac, char **av)
{
char buf[16];
char *str = buf;
char *extra = NULL;
int len;
if (!av[1])
return EXIT_FAILURE;
if ((len = snprintf(buf, 16, "%s", av[1])) >= 16)
if (extra = malloc((len + 1) * sizeof(char)))
snprintf(str = extra, len + 1, "%s", av[1]);
printf("%s/n", str);
if (extra)
free(extra);
return EXIT_SUCCESS;
}
The format control string, format
, should be interpreted as a multibyte character sequence but it is not. Apart from that, these functions comply with the ISO C 89 formatting requirements specified for the fprintf(3) function (section 7.9.6.1).
Even though snprintf(3) is an ISO C 99 function (section 7.19.6.5), this implementation does not support the new ISO C 99 formatting conversions or length modifiers (i.e. %hh[diouxXn]
, %ll[diouxXn]
, %j[diouxXn]
, %z[diouxXn]
, %t[diouxXn]
, %ls
, %lc
and %[aAF]
). The main reason is that the local system's sprintf(3) function is used to perform floating point formatting. If the local system can support %[aA]
, then you must have C99 already and so you must also have snprintf(3) already.
If snprintf(3) or vsnprintf(3) require more than 512 bytes of space in which to format a floating point number, but fail to allocate the required space, the floating point number will not be formatted at all and processing will continue. There is no indication to the client that an error occurred. The chances of this happening are remote. It would take a field width or precision greater than the available memory to trigger this bug. Since there are only 15 significant digits in a double and only 18 significant digits in an 80 bit long double (33 significant digits in a 128 bit long double), a precision larger than 15/18/33 serves no purpose and a field width larger than the useful output serves no purpose.
分享到:
相关推荐
strncpy, strncat和snprintf的区别,字符串拷贝,最好用snprintf。
用于了解安全函数strcpy_s、strncpy_s、snprintf_s、memcpy_s
在编程中,需要关注snprintf()的两个问题:一是它的返回值,二是它的第二个参数。
独立的snprintf和vsnprintf 该存储库中包含一个相对简单的snprintf和vsnprintf ,我在一两个小时的时间内编写了这些信息,用于业余爱好者的微内核。 我发现自己过去几次编写此代码或类似代码,因此决定编写一个涵盖...
inttypes.h snprintf.c snprintf.h stdint.h
一种snprinf实现来自ijs.si 版本号2.2
问题:函数memcpy(dest, src, sizeof(dest))、strncpy(dest, src, sizeof(dest))和snprintf(dest, sizeof(dest), “%s”, src)都可以将src字符串中的内容拷贝到dest字符串中。哪一种方式效率最高呢?就是说,哪种...
snprintf的正确用法:snprintf(dest, sizeof(dest), “%s”, src); strncpy的问题:1.size一定要用sizeof(dest)或sizeof(dest)-1,不可误用sizeof(src). 2.手工填0. 务必要把dest的最后一个字节手工设置为0. 因为...
以下是对snprintf函数的具体使用方法进行了详细的分析介绍,需要的朋友可以过来参考下
#字符串工具C++ 中常见字符串操作任务的助手。 ##用法# include < stringtools>using namespace str ;std::string text = format( " hello %s " )( " world " );std::vector<std> v = split( " , " )( " hello, ...
len = snprintf(buf, size, "%s", value); // printf("****wyb %s:%d/%s()! buf=%s len=%d\n", __FILE__, __LINE__, __func__, buf, len); break; } fclose(fd); return 0; } int main(int ...
tess4j的demo开发, 中文识别率高,把项目导入到eclipse中无需修改,使用Junit直接运行Tesseract1Test即可看到效果
snprintf( config.sql_DataBase , sizeof( config.sql_DataBase) , param ); printf("\n登陆数据库名:%s",config.sql_DataBase); } else if( strcmp( command , "sql_Table" ) == 0 ){ strcmp( config....
1、#define snprintf _snprintf 2、int InitService();函数声明放在ServiceMain()函数前面; 3、int InitService()需要有返回值; 不知道算不算一个漏洞,但是确实有效。 在int InitService()中设置断点时候好像...
详细的介绍SDP协议,包括各个字段的含义,以及一些具体的例子
snprintf的引入是为了解决 sprintf函数缓冲区溢出问题。 二、scanf函数族用于分析输入字符串,并将字符 序列转换成指定类型的变量。格式之后的个参数 包含了变量的地址,以用转换结果初始化这些变量。
"snprintf(filter_args, sizeof(filter_args), "movie=%s[wm];[in][wm]overlay=5:5[out]", logoPath);"解说: [in]表示 初始化滤镜的 inputs->name = av_strdup("out"); [out]表示 初始化滤镜的 %s 是格式化字符串中...
snprintf(sysport, sizeof(sysport), "/sys/class/tty/%s", &ttyport[strlen("/dev/")]); count = readlink(sysport, syspath, sizeof(syspath) - 1); if (count (":1.0/tty")) return; //ttyUSB0 -> ../....