Literales de cadena
Contenido |
[editar] Sintaxis
" secuencia-de-caracteres-s(opcional)"
|
(1) | ||||||||
L" secuencia-de-caracteres-s(opcional)"
|
(2) | ||||||||
u8" secuencia-de-caracteres-s(opcional)"
|
(3) | (desde C++11) | |||||||
u" secuencia-de-caracteres-s(opcional)"
|
(4) | (desde C++11) | |||||||
U" secuencia-de-caracteres-s(opcional)"
|
(5) | (desde C++11) | |||||||
prefijo(opcional) R" secuencia-de-caracteres-d(opcional)( secuencia-de-caracteres-r(opcional)) secuencia-de-caracteres-d(opcional)"
|
(6) | (desde C++11) | |||||||
[editar] Explicación
secuencia-de-caracteres-s | - | Una secuencia de uno o más carácter-s |
carácter-s | - | Uno de
|
carácter-s-básico | - | Un carácter del juego de caracteres fuente (hasta C++23)juego de caracteres de traducción (desde C++23), excepto las comillas dobles ", barra inversa \, o carácter de nueva línea |
prefijo | - | Uno de L , u8 , u , U .
|
secuencia-de-caracteres-d | - | Una secuencia de uno o más carácter-d, como máximo de 16 caracteres. |
carácter-d | - | Un carácter del juego de caracteres fuente básico (hasta C++23)juego de caracteres básicos (desde C++23), excepto paréntesis, barra inversa y espacios. |
secuencia-de-caracteres-r | - | Una secuencia de uno o más carácter-r, excepto que no puede contener la secuencia de cierre) secuencia-de-caracteres-d" .
|
carácter-r | - | Un carácter del juego de caracteres fuente (hasta C++23)juego de caracteres de traducción (desde C++23). |
N
es el tamaño de la cadena en unidades de código de codificación reducida de ejecución (hasta C++23)codificación de literal ordinario (desde C++23), incluyendo el terminador nulo.N
es el tamaño de la cadena en unidades de código de la codificación ancha de ejecución (hasta C++23)codificación de literal ancho (desde C++23), incluyendo el terminador nulo.N
es el tamaño de la cadena en unidades del código UTF-8, incluyendo en terminador nulo.N
es el tamaño de la cadena en unidades del código UTF-16, incluyendo el terminador nulo.N
es el tamaño de la cadena en unidades de código UTF-32, incluyendo en terminador nulo.Cada carácter-s (originalmente de literales de cadena con formato) o carácter-r (originalmente de literales de cadena sin formato) (desde C++11) inicializa los elementos correspondientes en el objeto literal de cadena. Un carácter-s o carácter-r (desde C++11) corresponde a más de un elemento solamente si está representado por una secuencia de más de una unidad de código en la codificación de caracteres asociada del literal de cadena.
Si un carácter no tiene representación en la codificación de caracteres asociada,
|
(desde C++23) |
Cada secuencia numérica de escape corresponde a un solo elemento. Si el valor especificado por la secuencia de escape encaja dentro de la versión sin signo del tipo de elemento, el elemento tiene el valor especificado (que puede ser después de la conversión al tipo de elemento); de lo contrario (el valor especificado está fuera de rango), el literal de cadena está mal formado. (desde C++23)
[editar] Concatenación
Los literales de cadena que están uno al lado del otro se concatenan en la fase 6 de traducción (después del preprocesador). Es decir, "Hola," " mundo!" se une en la cadena (única) "Hola, mundo!". Si las dos cadenas tiene el mismo prefijo de codificación (o ninguno), la cadena resultante tendrá el mismo prefijo de codificación (o ningún prefijo).
Si una de las cadenas tiene prefijo y la otra no, la que no tiene se considera que tiene el mismo prefijo de codificación que la otra. L"Δx = %" PRId16 // en la fase 4, PRId16 se expande a "d" // en la fase 6, L"Δx = %" y "d" forman L"Δx = %d" Si un literal de cadena UTF-8 y un literal de cadena ancho están consecutivos, el programa está mal formado. |
(desde C++11) |
Cualquier otra combinación de prefijos de codificación puede ser o no ser admitida por la implementación. La implementación define el resultado de dicha concatenación. |
(desde C++11) (hasta C++23) |
Cualquier otra combinación de prefijos de codificación está mal formada. |
(desde C++23) |
[editar] Notas
El carácter nulo ('\0', L'\0', char16_t(), etc) siempre se añade al literal de cadena: entonces, un literal de cadena "Hello" es const char[6] conteniendo los caracteres 'H', 'e', 'l', 'l', 'o', y '\0'.
La implementación define la codificación de los literales de cadena ordinarios (1) y anchos (2). Por ejemplo, gcc los selecciona mediante las opciones de línea de comandos -fexec-charset y -fwide-exec-charset.
Los literales de cadena tienen duración de almacenamiento estática, y existen en memoria durante la vida del programa.
Se pueden usar los literales de cadena para inicializar arrays de caracteres. Si un array se inicializa como char str[] = "foo";, str contendrá una copia de la cadena "foo".
No se especifica si los literales de cadena pueden superponerse y si las evaluaciones sucesivas de un literal de cadena producen el mismo objeto. Esto quiere decir que los literales de cadena idénticos pueden o no comparase iguales cuando se comparan por puntero.
bool b = "bar" == 3+"foobar" // puede ser verdadero o falso, según defina la implementación
Intentar modificar un literal de cadena resulta en un comportamiento no definido: pueden estar almacenados en almacenamiento de solo lectura (como .rodata
) o combinado con otros literales de cadena:
const char* pc = "Hello"; char* p = const_cast<char*>(pc); p[0] = 'M'; // comportamiento no definido
Los literales de cadena son convertibles y asignables a char* o wchar_t* no constantes para ser compatibles con C, donde los literales de cadena son de tipos char[N] y wchar_t[N]. Esta conversión implícita está en desuso. |
(hasta C++11) |
Los literales de cadena no son convertibles ni asignables a CharT* no constantes. Se debe utilizar una conversión explícita (por ejemplo, |
(desde C++11) |
Un literal de cadena no es necesariamente una secuencia de caracteres terminadas con carácter nulo: si un literal de cadena contiene caracteres nulos, representa un array que contiene más de una cadena.
const char* p = "abc\0def"; // std::strlen(p) == 3, pero el array tiene tamaño 8
Si un dígito hexadecimal válido sigue a una secuencia de escape hexadecimal, podría fallar la compilación por una secuencia de escape inválida. Se puede usar concatenación de cadenas para evitar esto:
//const char* p = "\xfff"; // ERROR: secuencia de escape hexadecimal fuera de rango const char* p = "\xff""f"; // correcto: el literal es const char[3], contiene {'\xff','f','\0'}
Aunque está permitida la concatenación de literales de cadena anchos mixtos en C++11, todos los compiladores conocidos de C++ la rechazan, y se desconoce su experiencia de uso. Como resultado, la concatenación de literales anchos mixtos se elimina en C++23.
[editar] Ejemplo
#include <iostream> char array1[] = "Foo" "bar"; // igual char array2[] = { 'F', 'o', 'o', 'b', 'a', 'r', '\0' }; const char* s1 = R"foo( Hola Mundo )foo"; // igual const char* s2 = "\nHola\n Mundo\n"; // igual const char* s3 = "\n" "Hola\n" " Mundo\n"; const wchar_t* s4 = L"ABC" L"DEF"; // correcto, igual a const wchar_t* s5 = L"ABCDEF"; const char32_t* s6 = U"GHI" "JKL"; // correcto, igual a const char32_t* s7 = U"GHIJKL"; const char16_t* s9 = "MN" u"OP" "QR"; // correcto, igual a const char16_t* sA = u"MNOPQR"; // const auto* sB = u"Tipos" U"Mixtos"; // antes de C++23 puede o no estar admitido // por la implementación; mal formado desde C++23 const wchar_t* sC = LR"--(STUV)--"; // correcto, literal de cadena sin formato int main() { std::cout << array1 << ' ' << array2 << '\n' << s1 << s2 << s3 << std::endl; std::wcout << s4 << ' ' << s5 << ' ' << sC << std::endl; }
Salida:
Foobar Foobar Hola Mundo Hola Mundo Hola Mundo ABCDEF ABCDEF STUV
[editar] Informes de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
---|---|---|---|
CWG 1823 | C++98 | Está definido por la implementación si los literales de cadena son distintos. |
La distinción no está especificada, y el mismo literal de cadena puede crear objetos distintos. |
[editar] Véase también
Literales definidos por el usuario(C++11) | Literales con sufijo definidos por el usuario |
Documentación de C para Literales de cadena
|