如何将 UnicodeString 复制到 C++Builder Android 应用程序中的 wchar_t 数组?
How can I copy a UnicodeString to a wchar_t array in a C++Builder Android app?
我正在使用 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()
等等
请问我该怎么做?
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)
On macOS and iOS, char16_t
is not equivalent to wchar_t
(as it is on Windows):
- On Windows,
wchar_t
and char16_t
are both double-byte characters.
- On
macOS
, iOS
, and Android, however, a wchar_t
is a 4-byte character.
So, to declare UTF-16 constant strings, on Windows use either the L
or the u
prefix, whereas on macOS, iOS, and Android, use the u
prefix.
Example on Windows:
UnicodeString(L"Text"), UnicodeString(u"Text")
Example on macOS, iOS, and Android:
UnicodeString(u"Text")
Using the L
prefix for string literals on macOS, iOS, and Android is not, however, wrong. In this case, UTF-32 constant strings are converted to UTF-16 strings.
For portability, use the _D
macro to write constant strings that are prefixed accordingly with L
or u
. Example:
UnicodeString(_D("Text"))
为确保在所有平台上使用 UTF-16,System::WideChar
类型是 Windows 上的 wchar_t
和其他平台上的 char16_t
的别名。 UnicodeString
是 WideChar
个元素的容器。
因此,如果您对数组使用 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'[=10=]';
*/
#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'[=10=]';
#else
// unsupported wchar_t size!
#endif
否则,如果你想确保你的数组在所有平台上始终是 16 位 UTF-16,那么你需要在你的数组中使用 char16_t
或 WideChar
而不是 wchar_t
. u
前缀创建一个基于 char16_t
的文字,RTL 的 _D()
宏创建一个基于 WideChar
的文字(使用 L
或 u
根据平台),例如:
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'[=11=]'; // or: _D('[=11=]')
*/
我正在使用 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()
等等
请问我该怎么做?
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)
On macOS and iOS,
char16_t
is not equivalent towchar_t
(as it is on Windows):
- On Windows,
wchar_t
andchar16_t
are both double-byte characters.- On
macOS
,iOS
, and Android, however, awchar_t
is a 4-byte character.So, to declare UTF-16 constant strings, on Windows use either the
L
or theu
prefix, whereas on macOS, iOS, and Android, use theu
prefix.Example on Windows:
UnicodeString(L"Text"), UnicodeString(u"Text")
Example on macOS, iOS, and Android:
UnicodeString(u"Text")
Using the
L
prefix for string literals on macOS, iOS, and Android is not, however, wrong. In this case, UTF-32 constant strings are converted to UTF-16 strings.For portability, use the
_D
macro to write constant strings that are prefixed accordingly withL
oru
. Example:
UnicodeString(_D("Text"))
为确保在所有平台上使用 UTF-16,System::WideChar
类型是 Windows 上的 wchar_t
和其他平台上的 char16_t
的别名。 UnicodeString
是 WideChar
个元素的容器。
因此,如果您对数组使用 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'[=10=]';
*/
#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'[=10=]';
#else
// unsupported wchar_t size!
#endif
否则,如果你想确保你的数组在所有平台上始终是 16 位 UTF-16,那么你需要在你的数组中使用 char16_t
或 WideChar
而不是 wchar_t
. u
前缀创建一个基于 char16_t
的文字,RTL 的 _D()
宏创建一个基于 WideChar
的文字(使用 L
或 u
根据平台),例如:
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'[=11=]'; // or: _D('[=11=]')
*/