关于printf:C,sprintf_s的包装函数

C++, Wrapper function for sprintf_s

包括banned.h(Microsoft安全工具之一)后,编译器警告我sprintf()函数不安全,并且MSDN中心向我建议使用sprintf_s,因为我的项目是跨平台的,我为sprintf函数编写了一个包装器。

1
2
3
4
5
6
7
8
9
//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,...);

上给我一个错误

error C2059: syntax error : '...'

任何人都知道如何为sprintf_s()编写包装函数吗?

非常感谢。


...不会神奇地将函数声明转换为使用这些参数的其他调用。您必须包括可变参数的东西,并使用它来调用下一层。

步骤基本上是:

  • 包括stdarg标头。
  • 声明va_list
  • 呼叫va_start
  • 调用v*printf函数之一。
  • 呼叫va_end

例如,这是一个小程序,演示如何提供一个将格式化的输出写入字符串的野兽,类似于您看上去的样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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 ("%s\
"
, buff);

    return 0;
}

我,我倾向于忽略Microsoft关于sprintf不安全的建议。如果您不知道自己在做什么,那对任何工具都可以说是不安全的。如果您想成为一名优秀的C程序员,您将学习该语言的局限性和缺点。

包括在char*上使用sizeof的那个,期望它返回它指向的缓冲区的大小,而不是指针的大小:-)

但是,如果您想成为C开发人员,请成为C开发人员。尽管C和C具有许多共同点,但它们不是同一语言。 C主要包含很多C东西,因此您(大部分)可以采用已经编写的C代码并将其用于C应用程序中。

换句话说,如果它是C应用程序,请使用std::stringstd::stringstream(a)而不是char数组和s*printf调用。

您应该编写C代码,就像C位不存在一样。否则,您更像是C程序员而不是C程序员:-)

(a)当然,知识渊博的开发人员可能已经避开了stringstream内容固有的冗长性,并使用了fmtlib之类的东西(具有printf的简洁性,但类型安全性C开发者来欣赏)。

尤其是因为它已被购买到C 20中,它将成为基础的一部分,所有人都可以使用。