Introducción a C#
Por Nacho Cabanes, versión 0.93 de 16-abr-2010


(Nota: Estás viendo una versión del curso antigua, creada en 2009. Es recomendable que sigas la versión 2015, mucho más actualizada, con contenidos más detallados, más ejemplos y más ejercicios propuestos)

4.4. Cadenas de caracteres

4.4.1. Definición. Lectura desde teclado

Hemos visto cómo leer cadenas de caracteres (Console.ReadLine) y cómo mostrarlas en pantalla (Console.Write), así como la forma de darles un valor(=). También podemos comparar cual es su valor, usando ==, o formar una cadena a partir de otras si las unimos con el símbolo de la suma (+):

Así, un ejemplo que nos pidiese nuestro nombre y nos saludase usando todas estas posibilidades podría ser:

/*---------------------------*/
/*  Ejemplo en C# nº 42:     */
/*  ejemplo42.cs             */
/*                           */
/*  Cadenas de texto (1)     */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo42
{
 
  public static void Main()
  {
 
    string saludo = "Hola";
    string segundoSaludo;
    string nombre, despedida;
 
    segundoSaludo = "Que tal?";
    Console.WriteLine("Dime tu nombre... ");
    nombre = Console.ReadLine();    
 
    Console.WriteLine("{0} {1}", saludo, nombre);
    Console.WriteLine(segundoSaludo);
 
    if (nombre == "Alberto")
      Console.WriteLine("Dices que eres Alberto?");
    else
      Console.WriteLine("Así que no eres Alberto?");
 
    despedida = "Adios " + nombre + "!";
    Console.WriteLine(despedida);
  }
}
 

4.4.2. Cómo acceder a las letras que forman una cadena

Podemos leer (o modificar) una de las letras de una cadena de igual forma que leemos los elementos de cualquier array: si la cadena se llama "texto", el primer elemento será texto[0], el segundo será texto[1] y así sucesivamente.

Eso sí, las cadenas en C# no se pueden modificar letra a letra: no podemos hacer texto[0]=’a’. Para eso habrá que usar una construcción auxiliar, que veremos más adelante.

4.4.3. Longitud de la cadena.

Podemos saber cuantas letras forman una cadena con "cadena.Length". Esto permite que podamos recorrer la cadena letra por letra, usando construcciones como "for".

Ejercicio propuesto: Un programa te pida tu nombre y lo muestre en pantalla separando cada letra de la siguiente con un espacio. Por ejemplo, si tu nombre es "Juan", debería aparecer en pantalla "J u a n".

4.4.4. Extraer una subcadena

Podemos extraer parte del contenido de una cadena con "Substring", que recibe dos parámetros: la posición a partir de la que queremos empezar y la cantidad de caracteres que queremos obtener. El resultado será otra cadena:

saludo = frase.Substring(0,4);

Podemos omitir el segundo número, y entonces se extraerá desde la posición indicada hasta el final de la cadena.

4.4.5. Buscar en una cadena

Para ver si una cadena contiene un cierto texto, podemos usar IndexOf ("posición de"), que nos dice en qué posición se encuentra (o devuelve el valor -1 si no aparece):

if (nombre.IndexOf("Juan") >= 0) Console.Write("Bienvenido, Juan");

Podemos añadir un segundo parámetro opcional, que es la posición a partir de la que queremos buscar:

if (nombre.IndexOf("Juan", 5) >= 0) ...

La búsqueda termina al final de la cadena, salvo que indiquemos que termine antes con un tercer parámetro opcional:

if (nombre.IndexOf("Juan", 5, 15) >= 0) ...

De forma similar, LastIndexOf ("última posición de") indica la última aparición (es decir, busca de derecha a izquierda).

4.4.6. Otras manipulaciones de cadenas

Ya hemos comentado que las cadenas en C# son inmutables, no se pueden modificar. Pero sí podemos realizar ciertas operaciones sobre ellas para obtener una nueva cadena. Por ejemplo:

Un programa que probara todas estas posibilidades podría ser así:

/*---------------------------*/
/*  Ejemplo en C# nº 43:     */
/*  ejemplo43.cs             */
/*                           */
/*  Cadenas de texto (2)     */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo43
{
 
  public static void Main()
  {
 
    string ejemplo = "Hola, que tal estas";
 
    Console.WriteLine("El texto es: {0}", 
      ejemplo);
 
    Console.WriteLine("La primera letra es: {0}", 
      ejemplo[0]);
 
    Console.WriteLine("Las tres primeras letras son: {0}", 
      ejemplo.Substring(0,3));
 
    Console.WriteLine("La longitud del texto es: {0}", 
      ejemplo.Length);
 
    Console.WriteLine("La posicion de \"que\" es: {0}", 
      ejemplo.IndexOf("que"));
 
    Console.WriteLine("La ultima A esta en la posicion: {0}", 
      ejemplo.LastIndexOf("a"));
 
    Console.WriteLine("En mayúsculas: {0}", 
      ejemplo.ToUpper());
 
    Console.WriteLine("En minúsculas: {0}", 
      ejemplo.ToLower());
 
    Console.WriteLine("Si insertamos \", tio\": {0}", 
      ejemplo.Insert(4,", tio"));
 
    Console.WriteLine("Si borramos las 6 primeras letras: {0}", 
      ejemplo.Remove(0, 6));
 
    Console.WriteLine("Si cambiamos ESTAS por ESTAMOS: {0}", 
      ejemplo.Replace("estas", "estamos"));
 
  }
}
 

Y su resultado sería


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

Otra posibilidad interesante, aunque un poco más avanzada, es la de descomponer una cadena en trozos, que estén separados por una serie de delimitadores (por ejemplo, espacios o comas). Para ello se puede usar Split, que crea un array a partir de los fragmentos de la cadena, así:

/*---------------------------*/
/*  Ejemplo en C# nº 43b:    */
/*  ejemplo43b.cs            */
/*                           */
/*  Cadenas de texto (2b)    */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo43b
{
 
	public static void Main()
	{
 
		string ejemplo = "uno,dos.tres,cuatro";
		char [] delimitadores = {',', '.'};
		int i;
 
		string [] ejemploPartido = ejemplo.Split(delimitadores);
 
		for (i=0; i<ejemploPartido.Length; i++)
			Console.WriteLine("Fragmento {0}= {1}",
			    i, ejemploPartido[i]);
 
	}
}
 

Que mostraría en pantalla lo siguiente:


Fragmento 0= uno
Fragmento 1= dos
Fragmento 2= tres
Fragmento 3= cuatro

4.4.7. Comparación de cadenas

Sabemos comprobar si una cadena tiene exactamente un cierto valor, con el operador de igualdad (==), pero no sabemos comparar qué cadena es "mayor" que otra, algo que es necesario si queremos ordenar textos. El operador "mayor que" (>) que usamos con los números no se puede aplicar directamente a las cadenas. En su lugar, debemos usar "CompareTo", que devolverá un número mayor que 0 si la nuestra cadena es mayor que la que indicamos como parámetro (o un número negativo si nuestra cadena es menor, o 0 si son iguales):

if (frase.CompareTo("hola") > 0)
	Console.WriteLine("Es mayor que hola");

También podemos comparar sin distinguir entre mayúsculas y minúsculas, usando String.Compare, al que indicamos las dos cadenas y un tercer dato "true" cuando queramos ignorar esa distinción:

if (String.Compare(frase, "hola", true) > 0)
	Console.WriteLine("Es mayor que hola (mays o mins)");

Un programa completo de prueba podría ser así:

/*---------------------------*/
/*  Ejemplo en C# nº 43c:    */
/*  ejemplo43c.cs            */
/*                           */
/*  Cadenas de texto (2c)    */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo43c
{
 
	public static void Main()
	{
 
		string frase;
 
		Console.WriteLine("Escriba una palabra");
		frase = Console.ReadLine();
 
		// Compruebo si es exactamente hola
		if (frase == "hola")
			Console.WriteLine("Ha escrito hola");
 
		// Compruebo si es mayor o menor
		if (frase.CompareTo("hola") > 0)
			Console.WriteLine("Es mayor que hola");
		else if (frase.CompareTo("hola") < 0)
			Console.WriteLine("Es menor que hola");
 
		// Comparo sin distinguir mayúsculas ni minúsculas
		bool ignorarMays = true;
		if (String.Compare(frase, "hola", ignorarMays) > 0)
			Console.WriteLine("Es mayor que hola (mays o mins)");
		else if (String.Compare(frase, "hola", ignorarMays) < 0)
			Console.WriteLine("Es menor que hola (mays o mins)");
		else 
			Console.WriteLine("Es hola (mays o mins)");
 
	}
}
 

Si tecleamos una palabra como "gol", que comienza por G, que alfabéticamente está antes de la H de "hola", se nos dirá que esa palabra es menor:


Escriba una palabra
gol
Es menor que hola
Es menor que hola (mays o mins)

Si escribimos "hOLa", que coindice con "hola" salvo por las mayúsculas, una comparación normal nos dirá que es mayor (las mayúsculas se consideran "mayores" que las minúsculas), y una comparación sin considerar mayúsculas o minúsculas nos dirá que coinciden:


Escriba una palabra
hOLa
Es mayor que hola
Es hola (mays o mins)

4.4.8. Una cadena modificable: StringBuilder

Si tenemos la necesidad de poder modificar una cadena letra a letra, no podemos usar un "string" convencional, deberemos recurrir a un "StringBuilder", que sí lo permiten pero son algo más complejos de manejar: hay de reservarles espacio con "new" (igual que hacíamos en ciertas ocasiones con los Arrays), y se pueden convertir a una cadena "convencional" usando "ToString":

/*---------------------------*/
/*  Ejemplo en C# nº 44:     */
/*  ejemplo44.cs             */
/*                           */
/*  Cadenas modificables     */
/*  con "StringBuilder"      */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
using System.Text; // Usaremos un System.Text.StringBuilder
 
public class Ejemplo44
{
 
  public static void Main()
  {
    StringBuilder cadenaModificable = new StringBuilder("Hola");
    cadenaModificable[0] = 'M';
    Console.WriteLine("Cadena modificada: {0}",
      cadenaModificable);
 
    string cadenaNormal;
    cadenaNormal = cadenaModificable.ToString();
    Console.WriteLine("Cadena normal a partir de ella: {0}",
      cadenaNormal);      
  }
}
 

Ejercicio propuesto:

4.4.9. Recorriendo con "foreach"

Existe una construcción parecida a "for", pensada para recorrer ciertas estructuras de datos, como los arrays (y otras que veremos más adelante).

Se usa con el formato "foreach (variable in ConjuntoDeValores)":

/*---------------------------*/
/*  Ejemplo en C# nº 45:     */
/*  ejemplo45.cs             */
/*                           */
/*  Ejemplo de "foreach"     */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo45
{
 
  public static void Main()
  {
    int[] diasMes = {31, 28, 21};
    foreach(int dias in diasMes) {
      Console.WriteLine("Dias del mes: {0}", dias);   
    }
 
    string[] nombres = {"Alberto", "Andrés", "Antonio"};
    foreach(string nombre in nombres) {
      Console.Write(" {0}", nombre);   
    }
    Console.WriteLine();
 
    string saludo = "Hola";
    foreach(char letra in saludo) {
      Console.Write("{0}-", letra);   
    }
    Console.WriteLine();
 
  }
}