【问题标题】:How can I copy a UnicodeString to a wchar_t array in a C++Builder Android app?如何将 UnicodeString 复制到 C++Builder Android 应用程序中的 wchar_t 数组?
【发布时间】:2020-06-03 16:42:33
【问题描述】:

我正在使用 C++Builder 10.3 Rio 为 Android 开发一个多平台应用程序。

我有一个数据数组如下:

typedef struct recordstruct
{
    bool shop;
    bool bought;
    wchar_t description[80];
} recordtype;

recordtype MasterItems[MAXITEMS]=
{
    false,false,L"Apples",
    false,false,L"Apricots",
    false,false,L"Avocado",
...
...
};

我已将其复制到 TEdit,并希望将值返回到 MasterItems 数组。

我曾经使用c_str()mbstowcs()strcpy()/wcscpy()等。

请问我该怎么做?

【问题讨论】:

    标签: android unicode-string c++builder-10.3-rio


    【解决方案1】:

    UnicodeString 在所有平台上都是 UTF-16 编码的字符串。但是,wchar_t 是一种 16 位类型,仅在 Windows 上用于 UTF-16 数据。在其他平台上,wchar_t 是用于 UTF-32 数据的 32 位类型。

    这在 Embarcadero 的 DocWiki 中有记录:

    String Literals char16_t and wchar_t on macOS and iOS
    (Android 也包括在内)

    在 macOS 和 iOS 上,char16_t 不等同于 wchar_t(就像在 Windows 上一样):

    • 在 Windows 上,wchar_tchar16_t 都是双字节字符。
    • 但在 macOSiOS和 Android 上,wchar_t 是一个 4 字节字符。

    因此,要声明 UTF-16 常量字符串,在 Windows 上使用 Lu 前缀,而在 macOS、iOS、和 Android 上,使用 u 前缀.

    Windows 上的示例:

    UnicodeString(L"Text"), UnicodeString(u"Text")

    macOS、iOS、和 Android 上的示例:

    UnicodeString(u"Text")

    但是,在 macOS、iOS、 和 Android 上对字符串文字使用 L 前缀并没有错。在这种情况下,UTF-32 常量字符串被转换为 UTF-16 字符串。

    为了便于移植,请使用_D 宏来编写相应前缀为Lu 的常量字符串。示例:

    UnicodeString(_D("Text"))

    为确保在所有平台上使用 UTF-16,System::WideChar 类型是 Windows 上 wchar_t 和其他平台上 char16_t 的别名。 UnicodeStringWideChar 元素的容器。

    因此,如果您对数组使用 wchar_t,那么在非 Windows 平台上,您需要先在运行时将 UnicodeString 转换为 UTF-32,例如使用 RTL 的 UnicodeStringToUCS4String() 函数,然后再使用然后可以将该数据复制到您的数组中,例如:

    typedef struct recordstruct
    {
        bool shop;
        bool bought;
        wchar_t description[80];
    } recordtype;
    
    recordtype MasterItems[MAXITEMS]=
    {
        false,false,L"Apples",
        false,false,L"Apricots",
        false,false,L"Avocado",
        ...
    };
    
    ...
    
    #if defined(WIDECHAR_IS_WCHAR) // WideChar = wchar_t = 2 bytes
    
    StrLCopy(MasterItems[index].description, Edit1->Text.c_str(), std::size(MasterItems[index].description)-1); // -1 for null terminator
    
    /* or:
    UnicodeString s = Edit1->Text;
    size_t len = std::min(s.Length(), std::size(MasterItems[index].destination)-1); // -1 for null terminator
    std::copy_n(s.c_str(), len, MasterItems[index].destination);
    MasterItems[index].destination[len] = L'\0';
    */
    
    #elif defined(WIDECHAR_IS_CHAR16) // WideChar = char16_t, wchar_t = 4 bytes
    
    UCS4String s = UnicodeStringToUCS4String(Edit1->Text);
    size_t len = std::min(s.Length-1, std::size(MasterItems[index].destination)-1); // UCS4String::Length includes the null terminator!
    std::copy_n(&s[0], len, MasterItems[index].destination);
    MasterItems[index].destination[len] = L'\0';
    
    #else
    
    // unsupported wchar_t size!
    
    #endif
    

    否则,如果您想确保您的阵列在所有平台上始终为 16 位 UTF-16,那么您需要在阵列中使用 char16_tWideChar 而不是 wchar_tu 前缀创建一个基于char16_t 的文字,而RTL 的_D() 宏创建一个基于WideChar 的文字(根据平台使用Lu),例如:

    typedef struct recordstruct
    {
        bool shop;
        bool bought;
        char16_t description[80]; // or: System::WideChar
    } recordtype;
    
    recordtype MasterItems[MAXITEMS]=
    {
        false,false,u"Apples", // or: _D("Apples")
        false,false,u"Apricots", // or: _D("Apricots")
        false,false,u"Avocado", // or: _D("Avocado")
        ...
    };
    
    ...
    
    StrLCopy(MasterItems[index].description, Edit1->Text.c_str(), std::size(MasterItems[index].description)-1); // -1 for null terminator
    
    /* or:
    UnicodeString s = Edit1->Text;
    size_t len = std::min(s.Length(), std::size(MasterItems[index].description)-1); // -1 for null terminator
    std::copy_n(s.c_str(), len, MasterItems[index].description);
    MasterItems[index].description[len] = u'\0'; // or: _D('\0')
    */
    

    【讨论】:

    • 谢谢雷米,你又救了我!
    猜你喜欢
    • 2011-02-06
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 2013-03-21
    相关资源
    最近更新 更多