我想知道是否有可能以及如何在 C++ 跨平台(C99,C++0x 独立)中实现snprintf
?有没有这样的提升?(我想知道要替换的 C++ 习语是snprintf(4)
什么?)
6 回答
std::ostringstream
可以替代使用snprintf
:
char buf[1024];
snprintf(buf, 1024, "%d%s", 4, "hello");
相等的:
#include <sstream>
std::ostringstream s;
s << 4 << "hello";
// s.str().c_str(); // This returns `const char*` to constructed string.
std::string s = boost::lexical_cast<std::string>(4) +
boost::lexical_cast<std::string>("hello");
是的,有支持格式化字符串的 Boost Format 库。
您可能想查看Qt QString 类,它提供了一个格式函数,它以一种非常面向对象的方式处理您想要的内容。您当然可以复制并从中学习。
是的,在标记为 boost 的问题中提及 Qt 可能是禁忌,但这个问题似乎比这更笼统。
既然提到了 Boost,那么 Boost.Format 有什么问题吗?
一旦我需要snprintf
在 Windows/Linux/HP-UX 上。我定义snprintf_safe
并在 Linux/HP-UX 上使用了snprinf
,在 Windows 上我使用了_snprintf
. 我记得_snprintf
如果存储数据所需的字节数超过允许的最大大小,那么写入 '\0' 的方法会有所不同。所以有必要处理。反正就是这样的宏:
#ifdef #WIN32
int snprintf_safe()
{
// make use of _snprintf
}
#else
#define snprintf_safe snprintf
#endif
std::ostringstream
或std::to_string
(c++11) 作为替代方案,但如果您需要更好的性能解决方案而无需额外的副本,或者只有 C 而不是 C++,您可能需要做其他事情:
MSVC不支持C99,因此没有snprintf
功能,只有他们自制的:
_snprintf
.
_snprintf
MSVC和官方 C99 (gcc,clang)的区别snprintf
:
返回值:
- MSVC:如果缓冲区大小不足以写入所有内容(不包括终止 null!),则返回 -1
- GCC:如果缓冲区足够大,则返回将写入的字符数
写入字节:
- MSVC:尽可能多写,如果没有空间就不要在最后写NULL
- GCC:尽可能多地写,总是写终止NULL(例外:buffer_size=0)
有趣的%n
微妙之处:如果您%n
在代码中使用,MSVC 将使其未初始化!如果由于缓冲区大小太小而停止解析,则 GCC 将始终写入如果缓冲区足够大时将写入的字节数。
所以我的建议是mysnprintf
使用vsnprintf
/编写你自己的包装函数_vsnprintf
,它给出相同的返回值并在两个平台上写入相同的字节(小心:%n
更难修复)。