简体   繁体   English

_vscwprintf 在 Mac OS X/Linux 上

[英]_vscwprintf on Mac OS X/Linux

I am porting an application on Mac OS X which was written for Windows.我正在 Mac OS X 上移植一个为 Windows 编写的应用程序。

In this application, there are many instances of _vscwprintf and _vscprintf.在这个应用程序中,有很多 _vscwprintf 和 _vscprintf 的实例。

This question helped me to implement _vsprintf on Mac OS X. But same technique for _vswprintf is not working.这个问题帮助我在 Mac OS X 上实现 _vsprintf。但是 _vswprintf 的相同技术不起作用。

Can anyone give the alternative of _vscwprintf on Mac OS X?任何人都可以在 Mac OS X 上提供 _vscwprintf 的替代方案吗? Or there any equivalent method for this?或者有任何等效的方法吗?

Microsoft describes the functions as returning the number of characters that would be used if the string were formatted — note that they are documented as not including the null terminator. Microsoft将这些函数描述为返回格式化字符串时将使用的字符数 - 请注意,它们被记录为不包括空终止符。

int _vscprintf(
   const char *format,
   va_list argptr 
);
int _vscwprintf(
   const wchar_t *format,
   va_list argptr 
);

Initial answer初步答复

These functions can, therefore, be emulated with vsprintf() and vswprintf() :因此,可以使用vsprintf()vswprintf()模拟这些函数:

int _vscprintf(const char *format, va_list argptr)
{
    return(vsnprintf(0, 0, format, argptr));
}

 int _vscwprintf(const wchar_t *format, va_list argptr) { return(vswprintf(0, 0, format, argptr)); }

It is up to you whether you remove the leading underscore;是否删除前导下划线取决于您; I would.我会。

Note that the _vscwprintf() implementation above is flawed;请注意,上面的_vscwprintf()实现是有缺陷的; see the code below.请参阅下面的代码。


vscprintf() and scprintf() vscprintf()scprintf()

Apologies: I wrote vsprintf() where I needed to write vsnprintf() (now fixed in the code above);道歉:我在需要写vsnprintf() vsprintf()地方写了vsprintf() (现在在上面的代码中修复了); however, vswprintf() already has the safer interface with the buffer length, so there is no vsnwprintf() .但是, vswprintf()已经具有缓冲区长度的更安全接口,因此没有vsnwprintf() There's a reason I prefer to test compile code before (or shortly after) posting it — it's been irksome not having the wherewithal to do so for a couple of days.我更喜欢在发布之前(或之后不久)测试编译代码是有原因的——几天来没有足够的资金这样做很令人厌烦。

Here's an SSCCE for vscprintf() (and scprintf() ):这是vscprintf() (和scprintf() )的scprintf()

#include <stdio.h>
#include <stdarg.h>

extern int vscprintf(const char *format, va_list argptr);
extern int scprintf(const char *format, ...);

int vscprintf(const char *format, va_list argptr)
{
    return(vsnprintf(0, 0, format, argptr));
}

int scprintf(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    int rc = vscprintf(format, args);
    va_end(args);
    return rc;
}

int main(void)
{
    int l = scprintf("%-8s %8d\n", "abc", 123);
    if (l > 0)
    {
        char buffer[l+1];
        int n = snprintf(buffer, sizeof(buffer), "%-8s %8d\n", "abc", 123);
        printf("%d = %d: %s", l, n, buffer);
    }
    return 0;
}

Output:输出:

18 = 18: abc           123

vscwprintf() and scwprintf() vscwprintf()scwprintf()

It turns out to be harder to simulate _vscwprintf() because the vswprintf() function is not as helpful as the vsnprintf() function.事实证明,模拟_vscwprintf()更难,因为vswprintf()函数不如vsnprintf()函数有用。 Specifically, vswprintf() reports an error if the formatted string won't fit in the formatted space, whereas vsnprintf() reports the number of characters that would have been needed in the buffer if it was going to fit.具体来说,如果格式化字符串不适合格式化空间, vswprintf()报告错误,而vsnprintf()报告缓冲区中需要的字符数(如果它适合)。 Hence, you have to work by trial and error:因此,您必须通过反复试验来工作:

#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>

extern int vscwprintf(const wchar_t *format, va_list argptr);
extern int scwprintf(const wchar_t *format, ...);

int vscwprintf(const wchar_t *format, va_list argptr)
{
    // Unlike vsnprintf(), vswprintf() does not tell you how many
    // characters would have been written if there was space enough in
    // the buffer - it just reports an error when there is not enough
    // space.  Assume a moderately large machine so kilobytes of wchar_t
    // on the stack is not a problem.
    int buf_size = 1024;
    while (buf_size < 1024 * 1024)
    {
        va_list args;
        va_copy(args, argptr);
        wchar_t buffer[buf_size];
        int fmt_size = vswprintf(buffer, sizeof(buffer)/sizeof(buffer[0]), format, args);
        if (fmt_size >= 0)
            return fmt_size;
        buf_size *= 2;
    }
    return -1;
}

int scwprintf(const wchar_t *format, ...)
{
    va_list args;
    va_start(args, format);
    int rc = vscwprintf(format, args);
    va_end(args);
    return rc;
}

int main(void)
{
    int l = scwprintf(L"%-8ls %8d\n", L"abc", 123);
    if (l > 0)
    {
        wchar_t buffer[l+1];
        int n = swprintf(buffer, sizeof(buffer)/sizeof(buffer[0]), L"%-8ls %8d\n", L"abc", 123);
        wprintf(L"%d = %d: %ls", l, n, buffer);
    }
    return 0;
}

When run, this produces the output运行时,这会产生输出

18 = 18: abc           123

(the same as before). (和以前一样)。

Tested on Mac OS X 10.8.3 using GCC 4.7.3 (which was built on Mac OS X 10.7.5, but that shouldn't cause any problems).在 Mac OS X 10.8.3 上使用 GCC 4.7.3 进行测试(它是在 Mac OS X 10.7.5 上构建的,但这不会导致任何问题)。

I recommend using open_wmemstream instead.我建议改用open_wmemstream Something like that:类似的东西:

#include <stdio.h>
#include <string>
#include <stdarg.h> 

using namespace std;

wstring wstring_format(const wchar_t* format, ...)
{
    wchar_t* buf;
    size_t size;
    FILE* stream = open_wmemstream(&buf, &size);

    va_list args;
    va_start(args, format);
    vfwprintf(stream, format, args);
    va_end(args);

    fclose(stream);
    wstring result(buf, buf + size);
    free(buf);

    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM