[C con Clase] Cadenas estilo C

Salvador Pozo salvador en conclase.net
Mie Ago 7 19:23:18 CEST 2013


Hola:

El pasado 2013-08-07 14:59:38, Sergio Torró escribió:
 
ST> Muchas gracias por tu respuesta Salvador, te has explicado perfectamente :-)
ST> Deduzco que si quisiera concatenar cadenas que el usuario introduce por
ST> teclado, tendría que asignar memoria dinámicamente para poder hacerlo,
ST> ¿verdad? 

Efectivamente, necesitarás memoria dinámica, pero eso plantea algunos problemas que pasaré a comentarte sobre tu programa.

ST> He escrito el siguiente código y me funciona bien, pero si hay
ST> algún detalle de los que no se ven a simple vista me encantaría saberlo ;-P
ST> int main(void)
ST> {
ST>        char *cad_input = new char;

Esto no es correcto. La expresión "new char" sólo reserva memoria para un carácter, y difícilmente podrás almacenar una cadena en un espacio tan pequeño.

Para reservar memoria para más de un carácter hay que usar el operador new[], de este modo:

char *cad_input = new char[32];

El problema de esto es que tenemos que dimensionar la cadena antes de saber qué tamaño va a tener, puesto que aún no hemos leído nada desde el teclado, ni tampoco podemos prever qué tipo de cadena va a introducir el usuario.

ST>        char cad_concat[] = "-> concatenado con este texto.";
ST>        char *cad_final = new char;

Lo mismo se aplica a cad_final.

ST>        cout << "Introduce una cadena: ";
ST>        cin >> cad_input;
ST>        strcat(cad_final, cad_input);

Aquí hay otro problema. No has inicializado la cadena cad_final, y concatenas el contenido inicial, que no conocemos, con el introducido por el usuario. El resultado es imprevisible.

ST>        strcat(cad_final, " ");
ST>        strcat(cad_final, cad_concat);
ST>        cout << endl << cad_final << endl;
ST>        delete cad_input;
ST>        delete cad_final;

Como dices en tu siguiente mensaje, si se usa new[] hay que usar delete[], pero en este caso no has usado los corchetes, por lo que, aún estando mal el programa, al menos los operadores new y delete son coherentes. :)

ST>        return 0;
ST> }

ST> Y en este último caso imagino que es mejor utilizar la asignación dinámica
ST> de memoria de C++ y evitar malloc() y realloc(), ¿verdad?

Programando en C++ siempre es preferible usar los operadores que las funciones para asignación de memoria. Más que nada porque los operadores se pueden sobrecargar o redefinir, para, por ejemplo, diseñar tu propia gestión de memoria.

Por cierto, que para evitar los inconvenientes con las cadenas es preferible usar la clase para cadenas definida en la cabecera <string>.

Tu programa, usando esa clase, queda así:
----8<------
#include <iostream>
#include <string>

using namespace std;

int main(void)
{
       string cad_input;
       string cad_concat("-> concatenado con este texto.");
       string cad_final;

       cout << "Introduce una cadena: ";
       getline(cin, cad_input);

       cad_final = cad_input + " " + cad_concat;

       cout << endl << cad_final << endl;

       return 0;
}
----8<------

Utilizo la función "getline" en lugar del operador >> para leer cadenas porque de ese modo se pueden leer espacios. El operador >> deja de leer al encontrar el primer espacio, y deja el resto de la cadena en el buffer de entrada, con lo que siguientes lecturas pueden dar un resultado inesperado.

En lugar de la función strcat, puedes usar el operador + para concatenar cadenas, o también el operador +=, si lo prefieres.

Recomiendo visitar el artículo del blog sobre validación de dato, ya que estamos hablando del tema. :)

http://blogconclase.wordpress.com/2013/06/07/validar-datos-en-c/

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net
Blog con Clase: http://blogconclase.wordpress.com
Con Clase: http://conclase.net


Más información sobre la lista de distribución Cconclase