在Mac OS X/Linux上为_vscwprintf [英] _vscwprintf on Mac OS X/Linux

查看:67
本文介绍了在Mac OS X/Linux上为_vscwprintf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Mac OS X上移植为Windows编写的应用程序.

I am porting an application on Mac OS X which was written for Windows.

在此应用程序中,有_vscwprintf和_vscprintf的许多实例.

In this application, there are many instances of _vscwprintf and _vscprintf.

问题帮助我在Mac OS X上实现_vsprintf.但是_vswprintf的相同技术无效.

This question helped me to implement _vsprintf on Mac OS X. But same technique for _vswprintf is not working.

在Mac OS X上,谁能提供_vscwprintf的替代方案?还是有与此等效的方法?

Can anyone give the alternative of _vscwprintf on Mac OS X? Or there any equivalent method for this?

推荐答案

Microsoft 将函数描述为返回格式化字符串时将使用的字符数-请注意,文档中记录的这些字符不包含空终止符.

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.

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

初始答案

因此,这些函数可以用 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.

请注意,上面的 _vscwprintf()实现存在缺陷;参见下面的代码.

Note that the _vscwprintf() implementation above is flawed; see the code below.

道歉:我写了 vsprintf(),在那里我需要写 vsnprintf()(现在已在上面的代码中修复);但是, vswprintf()已经具有缓冲区长度更安全的接口,因此没有 vsnwprintf().有一个原因我更喜欢在发布之前(或之后)测试编译代码-几天来没有足够的资金来做这令人讨厌.

Apologies: I wrote vsprintf() where I needed to write vsnprintf() (now fixed in the code above); however, vswprintf() already has the safer interface with the buffer length, so there is no 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.

这是 vscprintf()(和 scprintf())的SSCCE:

Here's an SSCCE for vscprintf() (and 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;
}

输出:

18 = 18: abc           123


vscwprintf() scwprintf()

事实证明,模拟 _vscwprintf()更加困难,因为 vswprintf()函数不如 vsnprintf()有用功能.具体来说,如果格式化的字符串不适合格式化空间,则 vswprintf()报告错误,而 vsnprintf()报告错误信息中需要的字符数.缓冲区是否适合.因此,您必须通过反复试验来工作:


vscwprintf() and scwprintf()

It turns out to be harder to simulate _vscwprintf() because the vswprintf() function is not as helpful as the vsnprintf() function. 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. 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;
}

运行时,将产生输出

18 = 18: abc           123

(与之前相同).

在Mac OS X 10.8.3上使用GCC 4.7.3(在Mac OS X 10.7.5上构建,但这不会引起任何问题)进行测试.

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/Linux上为_vscwprintf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆