Siguiendo una pregunta relacionada , me gustaría preguntar sobre los nuevos tipos de caracteres y literales de cadena en C ++ 11. Parece que ahora tenemos cuatro tipos de caracteres y cinco tipos de cadenas literales. Los tipos de personajes:
char a = '\x30'; // character, no semantics
wchar_t b = L'\xFFEF'; // wide character, no semantics
char16_t c = u'\u00F6'; // 16-bit, assumed UTF16?
char32_t d = U'\U0010FFFF'; // 32-bit, assumed UCS-4
Y los literales de cadena:
char A[] = "Hello\x0A"; // byte string, "narrow encoding"
wchar_t B[] = L"Hell\xF6\x0A"; // wide string, impl-def'd encoding
char16_t C[] = u"Hell\u00F6"; // (1)
char32_t D[] = U"Hell\U000000F6\U0010FFFF"; // (2)
auto E[] = u8"\u00F6\U0010FFFF"; // (3)
La pregunta es la siguiente: ¿Las referencias de caracteres \x
/ \u
/ \U
se pueden combinar libremente con todos los tipos de cadenas? ¿Todos los tipos de cadenas son de ancho fijo, es decir, las matrices contienen exactamente tantos elementos como aparecen en el literal, o las referencias a \x
/ \u
/ \U
se expanden en un número variable de bytes? ¿Las cadenas u""
y u8""
tienen semántica de codificación, por ejemplo, puedo decir char16_t x[] = u"\U0010FFFF"
, y el punto de código que no es BMP se codifica en una secuencia UTF16 de dos unidades? ¿Y de manera similar para u8
? En (1), ¿puedo escribir sustitutos solitarios con \u
? Finalmente, ¿alguna de las funciones de cadena es consciente de la codificación (es decir, son conscientes de los caracteres y pueden detectar secuencias de bytes no válidas)?
Esta es una pregunta un poco abierta, pero me gustaría obtener una imagen lo más completa posible de la nueva codificación UTF y las funciones de tipo del nuevo C ++ 11.
u"\U0010FFFF"
en un par sustituto.Respuestas:
No.
\x
se puede utilizar en cualquier cosa, pero\u
y\U
sólo se puede utilizar en las cadenas que son específicamente UTF-codificado. Sin embargo, para cualquier cadena codificada en UTF,\u
y\U
se puede utilizar como mejor le parezca.No de la manera que quieres decir.
\x
,\u
y\U
se convierten en función de la codificación de la cadena. El número de esoschar16_t
valores de "unidades de código" (utilizando términos Unicode. A es una unidad de código UTF-16) depende de la codificación de la cadena que los contiene. El literalu8"\u1024"
crearía una cadena que contiene 2char
s más un terminador nulo. El literalu"\u1024"
crearía una cadena que contiene 1char16_t
más un terminador nulo.El número de unidades de código utilizadas se basa en la codificación Unicode.
u""
crea una cadena codificada en UTF-16.u8""
crea una cadena codificada en UTF-8. Se codificarán según la especificación Unicode.Absolutamente no. La especificación prohíbe expresamente el uso de pares sustitutos UTF-16 (0xD800-0xDFFF) como puntos de código para
\u
o\U
.Absolutamente no. Bueno, permíteme reformular eso.
std::basic_string
no se ocupa de codificaciones Unicode. Ciertamente pueden almacenar cadenas codificadas en UTF. Pero sólo pueden pensar en ellos como secuencias dechar
,char16_t
ochar32_t
; no pueden pensar en ellos como una secuencia de puntos de código Unicode que están codificados con un mecanismo particular.basic_string::length()
devolverá el número de unidades de código, no puntos de código. Y obviamente, las funciones de cadena de la biblioteca estándar de C son totalmente inútilesSin embargo, debe tenerse en cuenta que la "longitud" de una cadena Unicode no significa el número de puntos de código. Algunos puntos de código combinan "caracteres" (un nombre desafortunado), que se combinan con el punto de código anterior. Por lo tanto, se pueden asignar múltiples puntos de código a un solo carácter visual.
Iostreams puede, de hecho, leer / escribir valores codificados en Unicode. Para hacerlo, tendrá que usar una configuración regional para especificar la codificación e imbuirla adecuadamente en los distintos lugares. Es más fácil decirlo que hacerlo, y no tengo ningún código para mostrarte cómo.
fuente
\x
no se pueden usar con cualquier cosa, por ejemplo, U + 1F984 no funcionará con el \ x prefijo y,\u
y\U
no se puede utilizar con los caracteres de control ASCII, al menos en Clang.