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? Or there any equivalent method for this?

有没有人可以在Mac OS X上提供替代的_vscwprintf ?或者有什么等价的方法?

1 个解决方案

#1


4

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; see the code below.

注意,上面的_vscwprintf()实现是有缺陷的;请参见下面的代码。


vscprintf() and scprintf()

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.

抱歉:我写了vsprintf(),我需要写vsnprintf()(现在在上面的代码中固定);但是,vswprintf()已经有了与缓冲区长度相比较安全的接口,所以没有vsnwprintf()。有一个原因,我喜欢在(或不久之后)发布编译代码——这是令人厌烦的,没有必要的资金,这样做几天。

Here's an SSCCE for vscprintf() (and scprintf()):

下面是vscprintf()(和scprintf())的SSCCE:

#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()

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:

由于vswprintf()函数没有vsnprintf()函数那么有用,所以模拟_vscwprintf()变得更加困难。具体地说,vswprintf()会报告一个错误,如果格式化的字符串不适合格式化的空间,而vsnprintf()则会报告在缓冲区中需要的字符数量。因此,你必须通过尝试和错误来工作:

#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上构建的,但这不应该造成任何问题)。

更多相关文章

  1. 字符串处理函数strcat和strtok
  2. Linux的时间函数(转载)
  3. 【linux】下的mkfifo 命令 和【C语言】中的mkfifo函数
  4. linux c (4) 进程终止-exit和_exit函数
  5. 看谁能找出bug★☆open函数总是返回-1
  6. [置顶] Linux C编程--string.h函数解析
  7. linux 下的时间获取函数
  8. linux c 网络编程, 常用网络函数,范例
  9. 如何测试已部署的Web应用程序

随机推荐

  1. 3.EditText控件
  2. Android:BottomNavigationView设置noActio
  3. android:configChanges
  4. android 实现 搜索保存历史记录功能
  5. 在android的Browser中设置User Agent
  6. Android系列教程之四:Android项目的目录结
  7. Android JNI环境搭建及开发入门
  8. Android activity四种启动模式及Flag
  9. 【Android】Android 代码判断当前设备是
  10. Android 布局 LinearLayout与RelativeLay