[英]How can I copy a UnicodeString to a wchar_t array in a C++Builder Android app?
I am using C++Builder 10.3 Rio developing a multi-platform app for Android.我正在使用 C++Builder 10.3 Rio 为 Android 开发多平台应用程序。
I have an array of data as follows:我有一个数据数组如下:
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",
...
...
};
I've copied this into a TEdit
, and want to get the value back to the MasterItems
array.我已将其复制到
TEdit
中,并希望将值返回到MasterItems
数组。
I used to use c_str()
and mbstowcs()
and strcpy()
/ wcscpy()
etc.我曾经使用
c_str()
和mbstowcs()
和strcpy()
/ wcscpy()
等。
How can I do this please?请问我该怎么做?
UnicodeString
is a UTF-16 encoded string on all platforms. UnicodeString
是所有平台上的 UTF-16 编码字符串。 However, wchar_t
is a 16bit type used for UTF-16 data only on Windows.但是,
wchar_t
是 16 位类型,仅用于 Windows 上的 UTF-16 数据。 On other platforms, wchar_t
is a 32bit type used for UTF-32 data.在其他平台上,
wchar_t
是用于 UTF-32 数据的 32 位类型。
This is documented in Embarcadero's DocWiki:这记录在 Embarcadero 的 DocWiki 中:
String Literals char16_t and wchar_t on macOS and iOS macOS 和 iOS 上的字符串文字 char16_t 和 wchar_t
(Android is included, too) (也包括Android)
On macOS and iOS,
char16_t
is not equivalent towchar_t
(as it is on Windows):在 macOS 和 iOS 上,
char16_t
不等同于wchar_t
(就像在 Windows 上一样):
- On Windows,
wchar_t
andchar16_t
are both double-byte characters.在 Windows 上,
wchar_t
和char16_t
都是双字节字符。- On
macOS
,iOS
, and Android , however, awchar_t
is a 4-byte character.但是,在
macOS
、iOS
和 Android上,wchar_t
是一个 4 字节字符。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.因此,要声明 UTF-16 常量字符串,在 Windows 上使用
L
或u
前缀,而在 macOS、iOS和 Android上使用u
前缀。Example on Windows:
Windows 示例:
UnicodeString(L"Text"), UnicodeString(u"Text")
Example on macOS, iOS, and Android :
macOS、iOS和 Android上的示例:
UnicodeString(u"Text")
Using the
L
prefix for string literals on macOS, iOS, and Android is not, however, wrong.但是,在 macOS、iOS和 Android上对字符串文字使用
L
前缀并没有错。 In this case, UTF-32 constant strings are converted to UTF-16 strings.在这种情况下,UTF-32 常量字符串被转换为 UTF-16 字符串。
For portability, use the
_D
macro to write constant strings that are prefixed accordingly withL
oru
.为了可移植性,使用
_D
宏来编写相应地以L
或u
为前缀的常量字符串。 Example:例子:
UnicodeString(_D("Text"))
To ensure UTF-16 is used on all platforms, the System::WideChar
type is an alias for wchar_t
on Windows and char16_t
on other platforms.为确保在所有平台上使用 UTF-16,
System::WideChar
类型是 Windows 上的wchar_t
和其他平台上的char16_t
的别名。 UnicodeString
is a container of WideChar
elements. UnicodeString
是WideChar
元素的容器。
So, if you use wchar_t
for your array, then on non-Windows platforms you will need to first convert your UnicodeString
to UTF-32 at runtime, such as with the RTL's UnicodeStringToUCS4String()
function, before you can then copy that data into your array, eg:因此,如果您对数组使用
wchar_t
,那么在非 Windows 平台上,您需要先在运行时将UnicodeString
转换为 UTF-32,例如使用 RTL 的UnicodeStringToUCS4String()
function,然后才能将该数据复制到您的数组,例如:
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
Otherwise, if you want to ensure your array is always 16bit UTF-16 on all platforms, then you need to use char16_t
or WideChar
instead of wchar_t
in your array.否则,如果您想确保您的数组在所有平台上始终是 16 位 UTF-16,那么您需要在数组中使用
char16_t
或WideChar
而不是wchar_t
。 The u
prefix creates a char16_t
-based literal, and the RTL's _D()
macro creates a WideChar
-based literal (using L
or u
according to platform), eg: 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'\0'; // or: _D('\0')
*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.