8 Cadenas de caracteres

Antes de entrar en el tema de los arrays también conocidos como arreglos, tablas o matrices, veremos un caso especial de ellos. Se trata de las cadenas de caracteres, frecuentemente nombrados en inglés como strings.

Nota: en informática es frecuente usar términos en inglés, sobre todo cuando la traducción puede inducir a errores, como en este caso, en que string se suele traducir como cuerda o cadena.
Aunque array también se puede traducir como ristra o sarta, que en este caso parece más apropiado, en ningún texto de programación verás que se hable jamás de ristras o sartas de caracteres o enteros.

Una cadena en C++ es un conjunto de caracteres, o valores de tipo char, terminados con el carácter nulo, es decir el valor numérico 0. Internamente, en el ordenador, se almacenan en posiciones consecutivas de memoria. Este tipo de estructuras recibe un tratamiento muy especial, ya que es de gran utilidad y su uso es continuo.

La manera de definir una cadena es la siguiente:

char <identificador> [<longitud máxima>];

Nota: En este caso los corchetes no indican un valor opcional, sino que son literalmente corchetes, por eso están en negrita.

Cuando se declara una cadena hay que tener en cuenta que tendremos que reservar una posición para almacenar el carácter nulo terminador, de modo que si queremos almacenar la cadena "HOLA", tendremos que declarar la cadena como:

char Saludo[5];

Las cuatro primeras posiciones se usan para almacenar los caracteres "HOLA" y la posición extra, para el carácter nulo.

También nos será posible hacer referencia a cada uno de los caracteres individuales que componen la cadena, simplemente indicando la posición. Por ejemplo el tercer carácter de nuestra cadena de ejemplo será la 'L', podemos hacer referencia a él como Saludo[2].

Es muy importante tener presente que en C++, los índices tomarán valores empezando siempre en cero, así el primer carácter de nuestra cadena sería Saludo[0], que es la letra 'H'.

En un programa C++, una cadena puede almacenar informaciones en forma de texto, como nombres de personas, mensajes de error, números de teléfono, etc.

La asignación directa sólo está permitida cuando se hace junto con la declaración.

El siguiente ejemplo producirá un error en el compilador, ya que una cadena definida de este modo se considera una constante, como veremos en el capítulo de "arrays" o arreglos.

char Saludo[5]; 
Saludo = "HOLA"

La manera correcta de asignar una cadena es:

char Saludo[5]; 
Saludo[0] = 'H'; 
Saludo[1] = 'O'; 
Saludo[2] = 'L'; 
Saludo[3] = 'A'; 
Saludo[4] = 0;

O bien:

char Saludo[5] = "HOLA";

Si te parece un sistema engorroso, no te preocupes, existen funciones que facilitan la manipulación de cadenas.

De hecho, existen muchas de tales funciones, que permiten compararlas, copiarlas, calcular su longitud, imprimirlas, visualizarlas, guardarlas en disco, etc. Además, frecuentemente nos encontraremos a nosotros mismos creando nuevas funciones que básicamente hacen un tratamiento de cadenas.

En C existe una biblioteca estándar (disponible en todos los compiladores), llamada precisamente string. En C++ también existe una biblioteca para manipular cadenas, aunque en este caso se trata de una biblioteca de clases.

Comentarios de los usuarios (13)

Tony
2012-09-02 22:21:59

Hola!

Buen dia, Necesito hacer un programa donde se indique un numero y se sume esas mismas veces (series), que imprima cada suma, por ejemplo si pongo un 7 que me imprima 7 14 21 28 35 42 49. He reviaso la pagina (muy buena por cierto), pero no me he encontrado ejemplos o algo que me indique como hacerlo.

Estoy usando Dev C++. Si alguien me puede ayudar se lo voy a agradecer.

P. D. NUNCA HE PROGRAMADO.

Isaac
2012-11-01 20:45:48

Tony, si que te explica como hacerlo. Revisa los bucles.

Tania
2012-11-19 19:54:07

Hola, tengo un problema, pues estoy intentando hacer un programa en C++ con la librería <cstring> que me ponga la primera letra de cada palabra de una cadena de caracteres en mayúscula si está en minúscula y viceversa, y además el resto de letras las ponga en minúscula. Os agradecería vuestra ayuda.

Steven R. Davidson
2012-11-19 21:25:37

Hola Tania,

La solución es recorrer cada carácter de la cadena e ir cambiando los caracteres a los que quieres. Recomiendo usar 'tolower()' y 'toupper()' en el fichero de cabecera <cctype> para obtener el carácter en minúsculas y en mayúsculas, respectivamente.

Espero que esto te sirva.

Steven

Tania
2012-11-19 22:50:23

Muchas gracias por tu ayuda,pero sigo sin entender como explico que me cambie la primera letra de cada palabra de esa cadena, es decir, después de un espacio en blanco. Siento las molestias y de nuevo gracias.

Steven R. Davidson
2012-11-20 00:50:04

Hola Tania,

Releyendo ambos comentarios que haces, creo que tienes una sola cadena con varias palabras separadas por espacios blancos. Quieres cambiar la letra de cada subcadena.

La idea es parecida a la que comenté, pero ahora te interesa acceder a cada carácter de cada subcadena. Puedes usar la función 'strpbrk()' para buscar un espacio blanco y así poder tomar la subcadena que te interesa. Por ejemplo,

char szCadena[] = "hola a todo el mundo";
char *pszEspacio = strpbrk( szCadena, " \r\n\t" );
int n = pszEspacio - szCadena;

szCadena[0] = toupper( szCadena[0] );  // 'H'
pszEspacio[1] = toupper( pszEspacio[1] );  // 'A'
n = pszEspacio - szCadena;

pszEspacio = strpbrk( &szCadena[n+1], " \r\n\t" );
pszEspacio[1] = toupper( pszEspacio[1] );  // 'T'
n = pszEspacio - szCadena;
...

Como puedes ver, calculamos la cantidad de caracteres entre el espacio blanco y supuestamente el comienzo de la subcadena. Hacemos esto para ir avanzando en la obtención de la siguiente subcadena con 'strpbrk()'. Habría que hacer algunas comprobaciones para asegurarnos de que vamos bien encaminados, pero creo que se entiende la idea principal.

Por otro lado, dices que quieres cambiar las otras letras de cada palabra. Si esto es así, entonces creo que es más fácil recorrer todos los caracteres de la cadena e ir aplicando el criterio que te interesa a cada uno. Si te encuentras con un espacio blanco, lo ignoras y tomas en cuenta que hemos terminado una palabra y vamos a dar comienzo a otra. Al encontrarnos con una letra, entonces es la primera y aplicamos un criterio. Aplicamos otro criterio para las otras letras en la palabra.

Espero que esto te oriente.

Steven

celeste
2013-04-25 04:42:11

hola teng una tarea sobre un programa cadenas de caracteres y no se como hacerlo podria alguien ayudarme, he avanzado un poko al inicio con la informacion.... que sobre tod es muy buena pero si alguien puede explicarmelo como hacerl paso x paso se lo agradeceria es la primera vez que hago un program..gracias!!!!!!!!!

Nando
2013-09-03 20:07:18

Hola, porque cuando estoy ejecutando un programa sencillo, y estoy introduciendo una cadena de caracteres y le dejo espacios en blanco cuando doy enter el programa tiene un bucle infinito.

Por ejemplo cuando introduzco el dato de un nombre ej:

andres perez.

Steven R. Davidson
2013-09-04 17:12:54

Hola Nando,

La razón es que seguramente usas 'cin >>'. Esta operación automáticamente detiene la lectura al encontrarse con un espacio blanco: espacio (' '), nueva línea ('\n'), retorno de carro o de línea ('\r'), tabulación ('\t'), tabulación vertical ('\v'), y avance de página ('\f').

Sin ver el código fuente del bucle, no puedo decir cuál es el problema exacto. Es posible que realices otras lecturas después de la del nombre y el programa entra en conflicto al leer "basura". Por ejemplo, si lees el nombre y luego lees un entero, entonces al detener la lectura antes de tiempo, la lectura del entero no tiene sentido y se usa un entero indeseado.

Espero que esto aclare la duda.

Steven

Juanito
2013-09-15 02:09:17

Hola, excelente curso.

Tengo una pregunta, ¿es posible agregar una cadena de caracteres a una posición de un arreglo?

Por ejemplo:

char *a [5];

a[0] = "hola";

Steven R. Davidson
2013-09-15 04:35:31

Hola Juanito,

Hay que tener cuidado con el término "agregar". En tu ejemplo, realmente copiamos (agregamos) la dirección de memoria del comienzo de la cadena literal de caracteres, "hola". De hecho, para que tu ejemplo compile, hay que indicar 'const'. Esto es,

const char *a[5];

a[0] = "hola";

Esto es porque la cadena literal es de tipo 'const char *', ya que no está permitido modificar los caracteres en una cadena literal, que implícitamente implica que es una constante.

En general, puedes crear una array de punteros a caracteres, pero esas cadenas, que quieras "agregar", deben existir ya en memoria. Por ejemplo,

char str1[] = "hola";
char str2[] = "adios";
char str3[] = "mundo";

char *apCadenas[5];

apCadenas[0] = str1;
apCadenas[1] = str2;
apCadenas[2] = str3;

Espero que esto aclare la duda.

Steven

Raul Martinez
2013-10-18 03:07:03

Hola... Tengo un problema y quiero saber si me pueden ayudar.. Estoy realizando un programa paca calcular el valor de una propiedad.. Aumentando año con año dependiendo el porcentaje que ingresa el usuario... Mi programa ya hace los cálculos y muestra la cantidad de decimales que deseo..

Mi problema es que no puedo mostrar la separación de millares en los totales... Me podrían apoyar con ese asunto.. Muchas gracias..!!

#include <iostream>

#include <conio.h>

#include <math.h>

#include <stdio.h>

#include <iomanip.h>

#include <string.h>

using namespace std;

int main()

{

float x=2014, actu, pasos, n,z;

float valor,plus=0;

int j,i;

system("color 2e");

cout<<setw(60)<<"**********************************************"<<endl;

cout<<setw(60)<<"PROGAMA PARA CALCULAR EL VALOR DE TU PROPIEDAD"<<endl;

cout<<setw(62)<<"**********************************************\n\n"<<endl;

cout<<setw(72)<<"'OJO'... NO LE METAS LETRAS POR QUE TRUENA EL PROGRAMA..!!!"<<endl;

cout<<"\nIndica el valor actual de tu propiedad... ";

while (!(cin>>actu))

{

cout<<"\nEL DATO INGRESADO NO ES VALIDO!!!\n";

cout<<"\nPorfavor intenta de nuevo... INGRESA SOLO NUMEROS..!!! ";

cin.clear();

fflush(stdin);

}

cout<<"\nDime la plusvalia de tu propiedad... ";

while (!(cin>>n))

{

cout<<"\nEL DATO INGRESADO NO ES VALIDO!!!\n";

cout<<"\nPorfavor intenta de nuevo... INGRESA SOLO NUMEROS..!!! ";

cin.clear();

fflush(stdin);

}

plus= n/100;

cout<<"\nIndicame a cuantos años necesitas el calculo... ";

while (!(cin>>z))

{

cout<<"\nEL DATO INGRESADO NO ES VALIDO!!!\n";

cout<<"\nPorfavor intenta de nuevo... INGRESA SOLO NUMEROS..!!! ";

cin.clear();

fflush(stdin);

}

for ( i=x; i<=z+2013; i++ )

{

valor= actu + (plus * actu);

actu = valor;

cout<<setw(30)<<i<<" - "<<"$"<<fixed<<setprecision(2)<<valor<<endl;

}

system("PAUSE");

getch();

return 0;

}

Daniela Piñeros
2014-03-20 14:45:55

Mira es que me dejaron el siguiente ejercicio y no tengo ni idea como plantearlo porque no he visto funciones con cadena ni nada por el estilo ... Podrías guiarme ...Gracias

Elabore un programa en C++ que capture su nombre en una cadena de caracteres y su apellido en otra cadena de caracteres y aplicando las diferentes de funciones con cadenas determine:

1. cuántos caracteres tiene su nombre

2. cuántos caracteres tiene su apellido

3. cuántas vocales tiene su nombre

4. copie su apellido en la cadena donde está ubicado el nombre y muestre el contenido de dicha cadena.

5. compare el contenido de las cadenas y muestre un mensaje indicando si son iguales o diferentes.

6. concatene las cadenas y muestre el resultado