String
Arreglos de char
(ASCII) o wchar_t
(Unicode) se utilizan comúnmente para almacenar texto. Estos buffers tienen un término especial: cadenas. Son importantes, pero complicadas.
Cadenas C o Cadenas de bytes terminadas en nulo
Una cadena siempre es un carácter más grande de lo que parece. El elemento extra es el terminador nulo (cero binario, escrito como \0
). Esto es necesario porque generalmente se pasa un puntero a una cadena, en lugar del arreglo en sí.
Sin el terminador sería imposible determinar dónde termina la cadena y dónde comienza la siguiente variable, o simplemente la memoria no asignada. Esto es lo que es un desbordamiento de búfer, ¡y esos son malas noticias!
Crear desde un Literal de Cadena
char* MiCadena = "Hola mundo"; // ¡debe asignarse a un puntero!
Este código crea una cadena a partir de un string literal. Las comillas dobles son una sintaxis especial que genera un arreglo de char
a partir de su contenido. El código anterior:
- Asigna 12 bytes de memoria, en algún lugar arbitrario, para almacenar la cadena. Esto es un byte para cada carácter, más un undécimo automático para el terminador nulo.
- Crea un
char
puntero que contiene la dirección del primer carácter (H en este caso).
Los literales de cadena a menudo se manejan con variables const
. Esto se debe a que un literal de cadena permanecerá en la memoria durante toda la vida del proceso.
MiCadena
en el depurador de Visual Studio, verás la cadena completa. Este es un comportamiento especial para facilitar el examen de cadenas; estrictamente hablando, solo debería mostrarte el puntero (es decir, el primer carácter, H).Crear por Tamaño
char MiCadena[12]; // acepta un tamaño estático únicamente
int LongitudCadena = 12;
char* pMiCadena = new char[LongitudCadena]; // acepta un tamaño variable
delete[] pMiCadena; // siempre elimina / elimina[] cualquier cosa creada con 'new' después de usarla
Este código asigna dos cadenas de 12 bytes, pero no escribe nada en ellas (por lo que su contenido será ya sea en blanco o incomprensible). Deben ser asignadas, idealmente con una función de cadena como strcpy()
o sprintf()
.
La diferencia entre ellas es que una crea un arreglo en el espacio de memoria de la función, mientras que la otra crea un puntero en la función y usa new
para asignar la cadena en otro lugar. La ventaja de new
es que puedes asignar un arreglo de un tamaño determinado en tiempo de ejecución, pero el inconveniente es que si no eres meticuloso con la llamada a delete
(o delete[]
para arreglos) sufrirás una fuga de memoria.
Cadenas Unicode
Las cadenas Unicode se comportan de manera similar a las cadenas ASCII, pero son arreglos de wchar_t
. Se operan con su propio conjunto de funciones de cadena, normalmente con 'wc' o 'wcs' (cadena de caracteres anchos) en su nombre.
wchar_t* MiCadenaAncha = L"Здравей свят";
La L
marca la cadena literal como Unicode. Necesitas hacer esto incluso si los caracteres son todos compatibles con ASCII.
Funciones de Cadenas
Existen una multitud de funciones que procesan cadenas, de las cuales las variantes ASCII más comunes tienen equivalentes específicos de Source con V_*
. Consulta MSDN para una lista bastante completa, o busca en la Vista de Clases de VS "V_str".