【问题标题】:how implement function work as sprintf use wchar for parameter?如何实现函数作为 sprintf 使用 wchar 作为参数?
【发布时间】:2012-06-23 14:38:27
【问题描述】:

我用过ANDROID NDK。所以我想格式化一些东西。只用sprintf,但我不能用它 wchar_t。对我有帮助吗?

【问题讨论】:

    标签: printf wchar


    【解决方案1】:

    你可能想要swprintf 和朋友,假设 Android 拥有它,就像 Posix 和 Linux 系统一样。

    Glib(来自GTK)具有unicode manipulation 和string utilities 的函数。我相信你应该可以让它在 Android 上运行。

    【讨论】:

    • 是的。但是NDK可能没有实现这个功能,所以我想实现一个像swprintf这样的功能。
    • 如果NDK不提供,我建议使用提供类似功能的库,比如Glib(来自gtk.org ...)
    • glib 使用 trio 实现 g_snprintf 功能,但是 trio 只提供 char ,不支持宽字符,
    【解决方案2】:

    在 5.0 之前的 Android OS NDK 版本(“Lollipop”)中,sprintf() 不支持“%ls”(wchar_t 指针)格式说明符。因此,以下语句在 NDK(5.0 之前)下编译但无法正确执行:

    char buffer [1000];
    wchar_t *wp = L"wide-char text";
    
    sprintf (buffer, "My string is: %ls", wp);
    

    解决方法是使用任何一种开源 Wide-to-utf8 实现(例如the UTF8-CPP project)将 wchar_t 字符串转换为 UTF-8(即 char *),并将其指针传递给 sprintf:

    // WcharToUtf8: A cross-platform function I use for converting wchar_t string
    //              to UTF-8, based on the UTF8-CPP Open Source project
    bool WcharToUtf8 (std::string &dest, const wchar_t *src, size_t srcSize)
    {
        bool ret = true;
    
        dest.clear ();
    
        size_t wideSize = sizeof (wchar_t);
    
        if (wideSize == 2)
        {
            utf8::utf16to8 (src, src + srcSize, back_inserter (dest));
        }
        else if (wideSize == 4)
        {
            utf8::utf32to8 (src, src + srcSize, back_inserter (dest));
        }
        else
        {
            // sizeof (wchar_t) is not 2 or 4 (does it equal one?)!  We didn't 
            // expect this and need to write code to handle the case.
            ret = false;
        }
    
        return ret;
    }
    ...
    char buffer [1000];
    wchar_t wp = L"wide-char text";
    std::string utf8;
    
    WcharToUtf8 (utf8, wp, wcslen (wp));
    sprintf (buffer, "My string is: %s", utf8.c_str ());
    

    从 Android 5.0(“Lollipop”)开始,sprintf() 支持“%ls”格式说明符,因此上面的原始 sprintf() 代码可以正常工作。

    如果您的 Android NDK 代码需要在所有版本的 Android 上运行,您应该使用如下宏包装所有传递给 sprintf 的 wchar_t 指针:

    #define CONVERTFORANDROID(e) (GetSupportsSprintfWideChar () ? (void *) e : (void *) WcharToUtf8(e).c_str ())
    
    char buffer [1000];
    wchar_t *wp = L"wide-char text";
    
    sprintf (buffer, "My string is: %ls", CONVERTFORANDROID(wp));
    

    GetSupportsSprintfWideChar() 函数应该是一个本地函数,如果正在运行的 Android 操作系统是 5.0 或更高版本,则返回 true,而如果操作系统是 pre-5.0,则返回 false。

    【讨论】:

      猜你喜欢
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2021-12-07
      相关资源
      最近更新 更多