sprintf_s的包装器函数
C++, Wrapper function for sprintf_s
在加入ban .h(微软安全工具之一)后,编译器提示sprintf()
函数不安全,MSDN中心建议我使用sprintf_s
,由于我的项目是跨平台的,我为sprintf函数写了一个包装器
//safe function for sprintf();
void WrapperSprintf( char *buffer, const char *format, ... )
{
#ifdef _WIN32
sprintf_s(buffer, sizeof(buffer), format,...);
#else
sprintf(buffer, format, ...);
#endif
}
在sprintf_s(buffer, sizeof(buffer), format,...);
错误C2059:语法错误:'…'
谁知道如何为sprintf_s()
编写包装器函数?
...
不会神奇地从函数声明转换到使用这些参数的其他调用。你必须包含变量参数的东西,并使用它来调用下一级。
步骤基本如下:
- 包含
stdarg
头。 - 声明
va_list
. - call
va_start
. - 调用
v*printf
函数之一。 - call
va_end
.
例如,下面是一个小程序,它演示了如何提供一个野兽,它将格式化的输出写入字符串,类似于您所追求的:
#include <stdio.h>
#include <stdarg.h>
void x (char *buf, char *fmt, ...) {
va_list va;
va_start (va, fmt);
vsprintf (buf, fmt, va);
va_end (va);
}
int main (void) {
char buff[100];
x (buff, "Hello, %s, aged %d", "Pax", 40);
printf ("%sn", buff);
return 0;
}
对于我来说,我倾向于忽略微软关于sprintf
不安全的建议。只有当你不知道自己在做什么的时候,它才不安全,这也适用于任何工具。如果你想成为一名优秀的C程序员,你必须了解这种语言的局限性和缺点。
包括在char*
上使用sizeof
的地方,期望它返回它指向的缓冲区的大小,而不是指针的大小:-)
但是,如果你想成为一个 c++ 开发者,就是一个 c++开发者。虽然C和c++有很多共同之处,但它们不是同一种语言。c++主要包含了很多C语言的东西,所以你可以(大部分)把已经写好的C代码用在你的c++应用程序中。
换句话说,如果它是一个c++应用程序,使用std::string
和std::stringstream
(a)而不是char
数组和s*printf
调用。
你应该在编写c++代码时,就好像C位不存在一样。否则,你更像是一个c++程序员而不是c++程序员:-)
(a)当然,有知识的开发人员可能已经避开了stringstream
固有的冗长内容,而使用类似fmtlib
的东西(具有printf
的简洁,但具有c++开发人员所欣赏的类型安全)。
特别是,因为它将被纳入c++ 20,成为基础的一部分,每个人都可以使用。
- 将 N-arg 函数包装到另一个函数中
- 将函数包装器转换为 std::function
- C++函数包装器来捕获某些信号
- 考虑引用和常量的可变参数函数包装器
- 将此私有删除器函数包装在结构中的目的是什么?
- 处理模板函数包装中的void返回
- 如何使用可变模板编写通用函数包装器
- 其他成员函数的通用"成员函数"包装器?
- 为什么将函数包装到 lambda 中可能会使程序更快?
- 创建一个允许轻松创建虚拟函数包装器函数的C++宏
- 将 c++ 函数包装为 c#,具有结构的总动态大小
- 返回对 std::函数包装的 lambda 中静态变量的引用会导致段错误
- 标准库中是否有与 std::thread 的构造函数语义匹配的类型擦除函数包装器?
- 如何编写 C++ 类成员函数包装器
- 有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
- 任何返回类型的可变参数函数包装器
- 具有临时函数包装器的完美转发
- 推导成员函数包装器的返回类型时出错
- 使用可变参数模板函数包装基于省略号的函数
- 将C 模板构造函数包装在模板类中