3.0 Cadenas de texto¶
Una cadena (string) es una secuencia de caracteres. Es uno de los tipos más usados y tiene una propiedad importante: es inmutable, es decir, ningún método la cambia: todos devuelven una cadena nueva.
Recorrer y buscar¶
string palabra = "murciélago";
Console.WriteLine($"longitud: {palabra.Length}");
Console.WriteLine($"primera: {palabra[0]}, última: {palabra[^1]}");
Console.WriteLine($"posición de la c: {palabra.IndexOf('c')}");
Console.WriteLine($"posición de la z: {palabra.IndexOf('z')}");
Console.WriteLine($"¿contiene «cié»? {palabra.Contains("cié")}");
Console.WriteLine($"¿empieza por «mur»? {palabra.StartsWith("mur")}");
int vocales = 0;
foreach (char letra in palabra)
{
if ("aeiouáéíóú".Contains(letra))
{
vocales++;
}
}
Console.WriteLine($"vocales: {vocales}");
Salida:
longitud: 10
primera: m, última: o
posición de la c: 3
posición de la z: -1
¿contiene «cié»? True
¿empieza por «mur»? True
vocales: 5
texto[i]da el carácter de la posicióni(se empieza a contar en 0);texto[^1]es el último,texto[^2]el penúltimo...IndexOfdevuelve la posición de la primera coincidencia o -1 si no está.foreachrecorre un texto carácter a carácter.
Transformar¶
Como la cadena no cambia, el resultado de cada método hay que guardarlo:
string s = " Hola, Mundo ";
s.ToUpper(); // no hace nada útil: se descarta el resultado
Console.WriteLine($"[{s}]"); // sigue igual
string limpio = s.Trim();
Console.WriteLine($"[{limpio}]");
Console.WriteLine(limpio.ToUpper());
Console.WriteLine(limpio.ToLower());
Console.WriteLine(limpio.Replace("o", "0"));
Console.WriteLine(limpio.Substring(0, 4)); // desde la posición 0, 4 caracteres
Console.WriteLine(limpio[6..]); // desde la posición 6 hasta el final
Console.WriteLine(limpio[..4]); // desde el principio hasta la 4 (sin incluirla)
Console.WriteLine(limpio[^5..]); // los 5 últimos
string[] partes = "manzana,pera,uva".Split(',');
Console.WriteLine(partes.Length);
Console.WriteLine(string.Join(" | ", partes));
Console.WriteLine("7".PadLeft(3, '0'));
Salida:
[ Hola, Mundo ]
[Hola, Mundo]
HOLA, MUNDO
hola, mundo
H0la, Mund0
Hola
Mundo
Hola
Mundo
3
manzana | pera | uva
007
Los rangos ([inicio..fin]) funcionan como el slicing de Python: incluyen el inicio y no incluyen el final.
Construir un texto largo: StringBuilder
Como cada += crea una cadena nueva, concatenar miles de veces en un bucle es lento. En ese caso se usa StringBuilder:
using System.Text;
var sb = new StringBuilder();
for (int i = 1; i <= 5; i++)
{
sb.Append(i).Append(' ');
}
Console.WriteLine(sb.ToString().Trim());
Salida:
1 2 3 4 5
Los métodos más útiles¶
| Necesitas... | Usa... |
|---|---|
| Longitud | texto.Length |
| Buscar una posición | IndexOf("x"), LastIndexOf("x") (devuelven -1 si no está) |
| Saber si contiene, empieza o acaba | Contains, StartsWith, EndsWith |
| Mayúsculas y minúsculas | ToUpper(), ToLower() |
| Quitar espacios de los extremos | Trim(), TrimStart(), TrimEnd() |
| Reemplazar | Replace("viejo", "nuevo") |
| Un trozo | Substring(inicio, longitud) o texto[a..b] |
| Trocear y unir | Split(','), string.Join(", ", partes) |
| Rellenar | PadLeft(n, '0'), PadRight(n) |
| ¿Vacío? | string.IsNullOrEmpty(t), string.IsNullOrWhiteSpace(t) |
| Comparar sin mirar mayúsculas | string.Equals(a, b, StringComparison.OrdinalIgnoreCase) |
Unicode¶
Un char de C# es una unidad de UTF-16, y algunos caracteres (los emojis, por ejemplo) ocupan dos. Por eso Length puede no coincidir con lo que ve una persona:
using System.Globalization;
string s = "Hola 😀";
Console.WriteLine($"Length: {s.Length}");
Console.WriteLine($"caracteres que se ven: {new StringInfo(s).LengthInTextElements}");
Console.WriteLine($"Length de «é»: {"é".Length}");
Salida:
Length: 7
caracteres que se ven: 6
Length de «é»: 1
Para casi todo el texto en español (con tildes y la ñ) Length sirve. Si tienes que contar lo que ve el usuario en textos con emojis, usa StringInfo.
Errores frecuentes¶
| Error | Cómo evitarlo |
|---|---|
Llamar a ToUpper() y no guardar el resultado |
Recuerda: la cadena es inmutable; escribe s = s.ToUpper(); |
Substring con una longitud mayor que el texto |
Lanza ArgumentOutOfRangeException: comprueba Length antes |
Suponer que IndexOf devuelve un valor válido |
Devuelve -1 si no encuentra; compruébalo |
| Comparar sin tener en cuenta las mayúsculas | string.Equals(a, b, StringComparison.OrdinalIgnoreCase) |
Un += dentro de un bucle largo |
Usa StringBuilder |
Para practicar¶
Haz los ejercicios 3.0 de cadenas.