自定义sprintf(...)样式函数,只有可变输入

时间:2016-01-25 04:47:12

标签: c++ c++builder

唱Borland C ++ Builder 2009。

在一个与String类相当的自定义类中(至少为了这个Q)我有一个函数,如下所示:

(为此Q编辑了一下)

MyString &MyString::Sprintf(const wchar_t *Text, ...)
{
    wchar_t ResultStr[1000] ;
    va_list List ;
    va_start  (List, Text) ;
    int cnt = vswprintf (ResultStr, Text, List ) ;
    #ifdef _DEBUG
    if (cnt >= (int)sizeof(ResultStr)) {throw (sizeof(ResultStr)) ;}
    #endif
    va_end (List) ;
    my_internally_handled_string.assign(ResultStr) ;
    return *this;
}

我想调整这个函数(或另一个函数),只将变量作为输入,并使用类'内部管理的字符串作为Text函数的输入vswprintf()

这样的事情:

MyString &MyString::Sprintf(...)
{
    const wchar_t *Text = my_internally_handled_string.c_str() ;
    // ... Rest see above

然而,这并不起作用。 vswprintf抛出异常。 (在my_internally_handled_string中使用完全正常的文本进行测试)

我想知道它是否完全可能和/或我需要做些什么来让它按照我设想的方式工作?

1 个答案:

答案 0 :(得分:2)

variadicstdarg.h / cstdarg)的变量(或va_start())参数是从{C}继承的macros。第二个参数是最后一个非 - 变量参数(在您的情况下为const wchar_t *Text)。这需要作为计算以下变量参数的起始地址的参考点。如果在...之前没有这样的最后一个参数,则它没有参考点来查找变量参数。因此,您需要某些东西来提供它,例如虚拟参数。

您可以保留现有的功能签名

    MyString &MyString::Sprintf(const wchar_t *Text, ...)

除了调用Text之外,不要使用参数va_start(List, Text)。请记住,您可以将任何内容传递给vswprintf(),例如

    vswprintf(ResultStr, my_internally_handled_string.c_str(), List);

此外,不要将参数Text与同名的局部变量一起使用,特别是在调用va_start()之前,因为它需要参数作为起点。

另一件值得一提的关于C ++中变量参数的事情是don't use a reference variable作为...之前的最后一个参数。