Cadenas de C++

Las cadenas de C++ son mucho más modernas e intuitivas que las de C, y se usan a través de la clase string, para lo que es necesaro incluir la cabecera:


#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s1( "¡hola" );
    s1 += ", mundo!";

    cout << s1 << endl; // ¡Hola, mundo!
}


Sin necesidad de utilizar funciones, con sólo unos operadores, (+, +=,=), para conseguir concatenar o cambiar la cadena, tenemos cadenas intuitivas. El objeto cadena crece automáticamente para albergar los caracteres se le vayan añadiendo, así que no es necesario preocuparse por nada.

Es posible acceder a una cadena por un índice:


s1[ 1 ] = 'L'; // Ahora s1 es ¡Lola


Y recorrer una cadena fácilmente:


for (int i = 0; i < s1.length(); ++i) {
    cout << s1[ i ] << endl;
}



Si necesitamos la "versión C" de s1, para pasársela a una función que sólo acepte char *, podemos utilizar el método c_str():


for(char * p = s1.c_str(); *p != '\0';++p) {
    cout << *p << endl;
}


¡Cuidado! ... no es legal modificar la cadena s1 a través de s1.c_str() ... el comportamiento es indefinido.

Entrada/salida con cadenas

La entrada/salida en C++ es en teoría sencilla, eliminando la necesidad de realizar conversiones de número a cadena, y viceversa.

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string nombre;
int edad;

    cout << "Introduzca el nombre: ";
    cin >> nombre;

    cout << "Introduzca la edad: ";
    cin >> edad;

    cout << "\nInfo: " << nombre << ',' << edad << endl;
}

El problema es que, al pedir una cadena, cin distingue por defecto los espacios como identificadores, por lo que una entrada como "Homer Simpson" al preguntar el nombre será recortada a "Homer", y se tratará de asignar "Simpson" a la edad.  Para impedir este problema, lo más sencillo es incluir la cabecera utility, y emplear la función getline():


#include <iostream>
#include <string>
#include <utility>

using namespace std;

int main()
{
    string nombre;

    cout << "Introduzca el nombre:" << endl;
    getline( cin, nombre );

    cout << "\nInfo: " << nombre << endl;
}

Conversión de cadena a número, y número a cadena

El segundo problema, si la lectura se hace siempre mediante cadenas, a través de getline(), es convertir una cadena (texto) a número, y viceversa. Una forma muy sencilla de resolver el anterior problema consiste en utilizar la función atoi(), en la cabecera cstdlib.

#include <iostream>
#include <string>
#include <utility>
#include <cstdlib>

using namespace std;

int main()
{
    string nombre;
    string strEdad;
    int edad;

    // Pedir el nombre
    cout << "Introduzca el nombre:" << endl;
    getline( cin, nombre );

    // Pedir la edad
    cout << "Introduzca la edad:" << endl;
    getline( cin, strEdad );
    edad = atoi( strEdad.c_str() );

    // Visualizar
    cout << "\nInfo: " << nombre << ", " << edad << endl;
}

La función atoi() devuelve 0 en caso de que lo que se pase en la cadena no se corresponda con un número entero. El único problema consiste en que no se puede distinguir el caso en el que el usuario ha introducido realmente un cero del caso en el que el contenido de la cadena es erróneo.

El caso inverso es convertir un número a una cadena. En este escenario, el recurso más interesante es la clase ostringstream, en la cabecera sstream.

#include <iostream>
#include <sstream>
#include <string>
#include <utility>
#include <cstdlib>

using namespace std;

int main()
{
    ostringstream conversor;
    string nombre;
    string strEdad;
    int edad;
    string info;

    // Pedir el nombre
    cout << "Introduzca el nombre:" << endl;
    getline( cin, nombre );

    // Pedir la edad
    cout << "Introduzca la edad:" << endl;
    getline( cin, strEdad );
    edad = atoi( strEdad.c_str() );

    // Convertir toda la información a cadena
    conversor
<< "\nInfo: " << nombre << ", " << edad << endl;
    info = conversor.str();

    // Visualizar
    cout << info;
}

La clase ostringstream permite introducir datos de cualquier tipo dentro de ella. Con todos estos datos construye y mantiene una cadena que es después recuperable mediante el método str(), tal y como se aprecia en el ejemplo.