MSDN页面分别如下: spirntf_s: http://msdn.microsoft.com/zh-cn/library/ce3zzk1k%28VS.80%29.aspx _snprintf: http://msdn.microsoft.com/zh-cn/library/2ts7cx93%28v=VS.90%29.aspx _snprintf_s: http://msdn.microsoft.com/zh-cn/library/f30dzcf6.aspx 三个页面都有自己的例子。。其中后2个的例子比较多内容一些。 为免将来页面失效: int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... ); template <size_t size>int sprintf_s( char (&buffer)[size], const char *format [, argument] ... ); // C++ only int _snprintf( char *buffer, size_t count, const char *format [, argument] ... ); int _snprintf( char (&buffer)[size], size_t count, const char *format [, argument] ... ); // C++ only int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... ); int _snprintf_s( char (&buffer)[size], size_t count, const char *format [, argument] ... ); // C++ only 呼呼。。内容还挺多。 这里比较引人注目的是,_snprintf_s为什么在sizeOfBuffer的基础上,还要多加一个count? count似乎是用来控制理想的宽度的。 如果得到的字符串超过了count,于是会被截断到count的长度后面再加一个null-teminate 当然,更高优先级的应该是sizeOfBuffer,必须不超过这个大小。这个就说到点子上了。 如果应该输出的字符串的大小已经达到了sizeOfBuffer,那么就溢出了。溢出的情况下,sprintf_s函数把这当做一个错误,会把buffer缓冲区置为一个空字符串""。 而_snprintf_s的好处就是,有了count参数,输出的字符串就算超过缓冲区长度,仍然会有输出,输出字符串被截断到count大小,在这个大小的字符串后面加null-teminate。 当然,如果count被设置成和sizeOfBuffer同样大,或者不合理的更大,那么这个count参数就失去了意义。 这时候,如果输出字符串将要达到或者超过sizeOfBuffer,一样导致一个错误,输出缓冲区被置为空字符串。 因此,如果希望缓冲区被尽量利用,可以把count参数置为_TRUNCATE,这样的情况下,实际上效果相当于是将count设置为sizeOfBuffer - 1。 至于C语言环境下,sprintf_s与_snprintf的对比: 注意到,_snprintf的参数用的是count,而sprintf_s的参数用的是sizeOfBuffer。这很能说明问题。 看下对_snprintf的说明: Let len be the length of the formatted data string (not including the terminating null). len and count are in bytes for _snprintf, wide characters for _snwprintf. If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned. If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned. If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned. 也就是说,_snprintf的count参数明明白白的就是一个count。 如果输出字符串刚好达到count,由于期待的最大长度就是count,那么输出字符串肯定要完整,不能截断。 但是假如字符串缓冲区的大小其实就是count,这怎么办?MS VCRT的设计者认为,在这种情况下应该把输出字符串的长度告知调用者,让调用者来决定是否自己添加null-teminate。 换句话说,调用_snprintf时要注意了,必须检查_snprintf的返回值,如果返回值不是正数,那么还得注意你的字符串缓冲区并不是null-teminate结尾的。 总结来说,sprintf_s在缓冲区不够大时会失败,失败时缓冲区中是一个空字符串。 _snprintf不会失败,但是必须注意如果缓冲区不够大,缓冲区的内容将不是null-teminate的,必须自己注意字符串的结束。 _snprintf_s结合了2者的优点,只要count参数设置合理,函数就不会因缓冲区不够而失败。 但是观察_snprintf_s的说明,有一个很有趣的内容。 这3族函数中,有失败情况的2个函数sprintf_s和_snprintf_s中,(再次强调,我这里的失败的意思是,调用后缓冲区里是一个空字符串),_set_invalid_parameter_handler设置的错误处理器,在失败的情况下会被调用。 而截断的情况下,错误处理器并不会被调用。 VC的库开发者总是提供一些怪怪的东西。无论如何,让代码更加安全总是符合大家的总体期望的。 另外补充一下,查阅这些字符串安全函数的资料的时候要注意, 对微软来说,凡是限制字符串复制长度的函数,这些设计者仍然认为是不安全的,因为逻辑上来说, 这些长度参数只是限制了源字符串被复制的长度,而不是目标缓冲区的长度。 也就是说,微软的这些设计者认为,安全的方式其实是依赖C++的机制,辨认出目标缓冲区的真正大小,以此实现安全的复制。 |
sprintf_s与_snprintf与_snprintf_s
时间: 2024-10-29 19:06:19
sprintf_s与_snprintf与_snprintf_s的相关文章
C++ “sprintf_s”: 不是“`global namespace&#39;”的成员
最近从别的一个控制台项目复制了一些代码到dll项目中,编译后报错,提示:C++ “sprintf_s”: 不是“`global namespace'”的成员, 经检查,发现复制的代码中包含了 std::cout << "......" 猜测dll工程不支持这样的编译,删除后编译成功. http://stackoverflow.com/questions/3710168/how-do-i-build-notepad-with-visual-c-2010-express上有一个
sprintf_s的使用
int sprintf_s(char *restrict buffer, rsize_t bufsz, const char *restrict format, ...); sprintf_s原先只有windows的编译器才只支持,但是在C11之后,也加入了该函数. Linux中有类似的函数实现,但是不完全相同,snprintf: int snprintf( char *restrict buffer, int bufsz, const ch
int sprintf_s(char *,size_t,const char *,...)”: 不能将参数 2 从“const char [3]”转换为“size_t”
2014-03-02 20:14 在编译下列代码时,出现以下错误: cpp(23) : error C2664: “int sprintf_s(char *,size_t,const char *,...)”: 不能将参数 2 从“const char [3]”转换为“size_t” 请问这是什么意思?该怎么修改? #include<iostream> #include<string> #include<stdio.h> using namespace std; str
linux下sprintf_s函数的替代(转载)
转自:http://www.cnblogs.com/yeahgis/archive/2013/01/22/2872179.html windows平台下线程安全的格式化字符串函数sprint_s并非标准C函数,因此linux下无法使用,但可以使用snprintf函数代替. /*函数原型:*/ int snprintf(char *dest, size_t n, const char *fmt, ...); /*函数说明: 最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0.所以如果目标
snprintf/_snprintf 在不同平台间函数差异
原文是以MSDN的文档介绍为主.而且还是之前的版本.不知新版本有没有改变,一会儿安装好了VS2013 Express试试看. 这个函数最主要的问题是C标准中没有定义,是各个厂家自己提供的,gcc提供的就是snprintf,ms提供的是加了前下划线的版本.因而对于函数的行为没有标准的定义,存在实现上的差别.主要表现在返回值和输出缓冲区的行为上. gcc的版本会在源字符串长度>=size的情况下,对目标字符串的结尾自动添加"\0",返回值为源字符串长度: ms的版本会在源字符串长度&
C++ Unicode SBCS 函数对照表
来源:http://www.cnblogs.com/PiaoDbg/archive/2012/03/04/2379336.html Generic SBCS UNICODE TCHAR char wchar_t _TEOF EOF WEOF _TINT int wint_t _TSCHAR signed char wchar_t _TUCHAR unsigned char wchar_t _TXCHAR char wchar_t _T(x) x L __targv __argv __wargv
格式化字符串函数sprintf
sprintf.snprintf相关函数的主要功能是把格式化的数据写入某个字符串.如最常见的应用是将整数或浮点数转换为字符串. 1.sprintf 将格式化的数据写入字符串,并自动在末尾加上一个空字符'\0'. 原型: int sprintf ( char * str, const char * format, ... ); str: 要写入的字符串缓冲区地址 format: 格式化数据 返回:执行成功时,返回写入到字符个数. const int MAX_LEN = 5; char buf[MA
C++ Unicode SBCS 函数对照表,以备日后查阅(很全)
C++ Unicode SBCS 函数对照表,以备日后查阅 Generic SBCS UNICODE TCHAR char wchar_t _TEOF EOF WEOF _TINT int wint_t _TSCHAR signed char wchar_t _TUCHAR unsigned char wchar_t _TXCHAR char wchar_t __T(x) x L __targv __argv __wargv __tcserror _strerror __wcserror __t
【VC】warning C4996: &#39;XXXX&#39;: This function or variable may be unsafe.
关于VS系列使用 Unicode 格式产生以上警告: warning C4996: 'wcscpy': This function or variable may be unsafe. Consider using wcscpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. MSDN Generic-Text Routine Mappings TCHAR.H