25 febrero 2015

C++ para C# 3: Cadenas y teclado

Llega el momento de retomar la "chuleta rápida de C++ para gente que conoce C#". Vamos con ello... hoy toca hablar de las cadenas y del manejo de teclado...

El manejo de cadenas de texto en C++ es muy parecido al de C#. La lectura de teclado es muy simple: "cin" puede leer tanto números como cadenas. Vamos a ver primero un ejemplo en C# y su resultado, para luego convertirlo a C++:

 1: using System;
 2: 
 3: public class CadenasTeclado
 4: {
 5: 
 6:   public static void Main()
 7:   {
 8: 
 9:     string ejemplo = "Hola, que tal estas";
10:    
11:     string ejemplo2 = "Hola";
12:     string ejemplo3;
13:     ejemplo3 = " y hola";
14:     string ejemplo4 = ejemplo2+ejemplo3;
15:    
16:     if (ejemplo2 == "Hola")
17:       Console.WriteLine("El texto 2 es Hola");
18:        
19:     Console.WriteLine("El texto es: {0}",
20:       ejemplo);
21:      
22:     Console.WriteLine("La primera letra es: {0}",
23:       ejemplo[0]);
24:    
25:     Console.WriteLine("Las tres primeras letras son: {0}",
26:       ejemplo.Substring(0,3));
27: 
28:     Console.WriteLine("La longitud del texto es: {0}",
29:       ejemplo.Length);
30:    
31:     Console.WriteLine("La posicion de \"que\" es: {0}",
32:       ejemplo.IndexOf("que"));
33:    
34:     Console.WriteLine("La ultima A esta en la posicion: {0}",
35:       ejemplo.LastIndexOf("a"));
36:      
37:     Console.WriteLine("En mayúsculas: {0}",
38:       ejemplo.ToUpper());
39:      
40:     Console.WriteLine("En minúsculas: {0}",
41:       ejemplo.ToLower());
42:      
43:     Console.WriteLine("Si insertamos \", tio\": {0}",
44:       ejemplo.Insert(4,", tio"));
45:    
46:     Console.WriteLine("Si borramos las 6 primeras letras: {0}",
47:       ejemplo.Remove(0, 6));
48:    
49:     Console.WriteLine("Si cambiamos ESTAS por ESTAMOS: {0}",
50:       ejemplo.Replace("estas", "estamos"));
51:      
52:     // Y ahora vamos a leer desde teclado
53:    
54:     Console.Write("Dime tu nombre: ");
55:     string nombre = Console.ReadLine();
56:     Console.WriteLine("Hola {0}", nombre);
57:    
58:     Console.Write("Vamos a sumar dos números... Primero? ");
59:     int n1 = Convert.ToInt32( Console.ReadLine() );
60:     Console.Write("Segundo? ");
61:     int n2 = Convert.ToInt32( Console.ReadLine() );
62:     Console.WriteLine("Suma: {0}", n1+n2);
63:   }
64: }

Que mostraría algo como

El texto 2 es Hola
El texto es: Hola, que tal estas
La primera letra es: H
Las tres primeras letras son: Hol
La longitud del texto es: 19
La posicion de "que" es: 6
La ultima A esta en la posicion: 17
En mayúsculas: HOLA, QUE TAL ESTAS
En minúsculas: hola, que tal estas
Si insertamos ", tio": Hola, tio, que tal estas
Si borramos las 6 primeras letras: que tal estas
Si cambiamos ESTAS por ESTAMOS: Hola, que tal estamos
Dime tu nombre: yo
Hola yo
Vamos a sumar dos números... Primero? 1
Segundo? 3
Suma: 4


Al pasarlo a C++, deberemos tener en cuenta que:


  • Existen "cadenas al estilo C", definidas como "char*" o como "char[]", pero es preferible evitarlas. C++ propone un tipo "cadena de texto", llamado "string".
  • No usaremos "{0}" para posicionar los parámetros, sino que escribiremos varios valores separados por "<<".
  • Para comprobar el valor de una cadena no se debe usar "==", porque estaríamos comparando realmente si están en la misma posición de memoria. En vez de eso, debemos usar "cadena1.compare(cadena2)" (que tendrá como resultado 0 si son iguales).
  • Para extraer un carácter de la cadena se emplean corchetes, al igual que en C#, o bien se podría usar ".at(pos)".
  • La longitud no se halla con ".Length" sino con ".length()"
  • Para obtener una subcadena, no usaremos "Substring" sino ".substr", al que se le indica posición inicial y longitud.
  • Para buscar la primera aparición de un texto se usa "find" y para la última (primera desde la derecha), "rfind". Ambas devuelven el valor especial "string::npos" si no se encuentra.
  • No hay una forma de convertir a mayúsculas y minúsculas toda una cadena. En el fichero de cabecera "locale" existen un "toupper" y un "tolower" que se pueden aplicar letra a letra.
  • Para insertar una cadena en medio de otra se usa "insert" y para eliminar un fragmento se emplea "erase".
  • No podemos reemplazar un texto por otro todas las veces que aparezca. Existe un "replace", pero recibe la posición inicial, la longitud y la cadena que hay que incluir entre esas posiciones.
  • Las operaciones de modificación, como "insert", "erase" y "replace" no necesitan volcarse a una nueva cadena (aunque se puede), porque modifican la cadena de texto original.
  • Se puede leer tanto cadenas como números con "cin". Si la cadena puede contener espacios, habrá que usar "cin.getline", al que se le indica tanto la cadena en la que se quiere guardar como la longitud máxima permitida: "cin.getline(texto, 80);"

 

Con todos estos cambios, el fuente podría quedar así...

 1: #include <iostream>
 2: #include <locale>
 3: using namespace std;
 4:  
 5: int main () 
 6: {
 7:     locale zona;
 8:     string ejemplo = "Hola, que tal estas";
 9: 
10:     string ejemplo2 = "Hola";
11:     string ejemplo3;
12:     ejemplo3 = " y hola";
13:     string ejemplo4 = ejemplo2+ejemplo3;
14:    
15:     if (ejemplo2 == "Hola")
16:       cout << "El texto 2 es Hola" << endl;
17:        
18:     cout << "El texto es: " << ejemplo << endl;
19:      
20:     cout << "La primera letra es: " << ejemplo[0] << endl;
21:    
22:     cout << "Las tres primeras letras son: "  <<
23:         ejemplo.substr(0,3) << endl;
24: 
25:     cout << "La longitud del texto es: " << ejemplo.length() << endl;
26:    
27:     cout << "La posicion de \"que\" es: " <<
28:       ejemplo.find("que") << endl;
29:    
30:     cout << "La ultima A esta en la posicion: " <<
31:       ejemplo.rfind("a") << endl;
32:      
33:     cout << "En mayúsculas: ";
34:     for (size_t i=0; i<ejemplo.length(); i++)
35:         cout << toupper(ejemplo[i], zona);
36:     cout << endl;
37:      
38:     cout << "En minúsculas: ";
39:     for (size_t i=0; i<ejemplo.length(); i++)
40:         cout << tolower(ejemplo[i], zona);
41:     cout << endl;
42:      
43:     cout << "Si insertamos \", tio\": " <<
44:       ejemplo.insert(4,", tio") << endl;
45:    
46:     cout << "Si borramos las 6 primeras letras: " <<
47:       ejemplo.erase(0, 6) << endl;
48:    
49:     cout << "Si cambiamos ESTAS por ESTAMOS: " <<
50:       ejemplo.replace(ejemplo.find("estas"),5, "estamos") << endl;
51:      
52:     // Y ahora vamos a leer desde teclado
53:    
54:     cout << "Dime tu nombre: ";
55:     string nombre;
56:     cin >> nombre;
57:     cout << "Hola " << nombre << endl;
58:    
59:     cout << "Vamos a sumar dos números... Primero? " << endl;
60:     int n1, n2;
61:     cin >> n1;
62:     cout << "Segundo? " << endl;
63:     cin >> n2;
64:     cout << "Suma: " << n1+n2 << endl;
65:     
66:     return 0;
67: }

Para mañana, algo de arrays y de estructuras dinámicas...

Como siempre, si tienes dudas, ya sabes: usa los comentarios o el foro de C++ de AprendeAProgramar.