Ir al contenido
wannacode

Cadenas: trabajar con texto

En resumen: Una cadena (string) es texto, una secuencia de caracteres con índices desde 0: tiene una longitud y métodos para buscar, reemplazar, recortar, dividir en partes y comparar.

Problema

El código es correcto, pero no funciona

La tienda da un 10% de descuento con el código VERANO10. Una clienta lo copia del anuncio, pero lo escribe en minúsculas y sin querer pone un espacio delante:

string code = Console.ReadLine();
if (code == "VERANO10")
{
Console.WriteLine("10% de descuento");
}
else
{
Console.WriteLine("Código no válido");
}
Entrada
verano10
Salida
Código no válido

Para una persona, el código es el mismo. Para el programa, verano10 y VERANO10 son textos distintos: el primero tiene un carácter más, y las letras son otras. Tienes que poder mirar dentro de un texto y arreglarlo.

La idea

El texto es una secuencia de caracteres

El texto son caracteres colocados uno detrás de otro: letras, cifras, espacios, signos. Cada carácter tiene un índice, como en un array. El primero tiene el índice 0.

string code = "VERANO10";
Console.WriteLine(code.Length);
Console.WriteLine(code[0]);
Console.WriteLine(code[code.Length - 1]);
Salida
8
V
0
  • code.Length es el número de caracteres.
  • code[0] es el carácter con índice 0. El último carácter tiene el índice Length - 1.

Un solo carácter tiene su propio tipo: char. Se escribe entre comillas simples: 'V', '0', ' '. El texto va entre comillas dobles: "V" es un texto con un carácter, no un char.

Tanto en el texto como en el array, la longitud es Length, sin paréntesis.

Míralo

Carácter a carácter

¿Cuántas cifras tiene el número de teléfono? Recorres los índices desde 0 hasta el último y miras cada carácter:

string phone = "0888 123 456";
int digits = 0;
for (int i = 0; i < phone.Length; i++)
{
char c = phone[i];
if (c >= '0' && c <= '9')
{
digits++;
}
}
Console.WriteLine("Cifras: " + digits);
Salida
Cifras: 10

c >= '0' && c <= '9' funciona porque cada carácter es en realidad un número: su código en la tabla de caracteres. Las cifras de '0' a '9' tienen códigos seguidos, y también las letras de 'a' a 'z'. Por eso los caracteres se comparan como números.

Más precisamente, para curiosos
  • Para comprobaciones así hay métodos ya hechos: char.IsDigit(c), char.IsLetter(c), char.IsUpper(c), char.IsLower(c). También conocen letras que no están en el alfabeto inglés, como é o ñ.
  • El código de un carácter se obtiene con una conversión: (int) 'A' es 65. Al revés, (char) 66 es 'B'. Por eso 'a' + 1 es el número 98, no la letra b.
  • Sin índice: foreach (char c in phone) recorre directamente los caracteres del texto.

Pruébalo

¿Qué carácter?

¿Qué imprimirá el programa?

string word = "Factura";
Console.WriteLine(word[3]);
Console.WriteLine(word.Length);
Respuesta

La idea

Los métodos del texto

El texto trae métodos ya hechos: acciones que llamas con un punto después del texto. Este es el arreglo del código promocional:

string code = " verano10";
string clean = code.Trim().ToUpper();
Console.WriteLine("[" + clean + "]");
Console.WriteLine(clean == "VERANO10");
Salida
[VERANO10]
True

Trim() quita los espacios del principio y del final. ToUpper() pone todas las letras en mayúscula. Los métodos se pueden encadenar uno tras otro: el primero devuelve un texto, y el segundo se llama sobre él.

Algunos más, sobre una dirección de correo:

string email = "lucia.garcia@correo.es";
Console.WriteLine(email.Contains("@"));
Console.WriteLine(email.IndexOf("@"));
Console.WriteLine(email.Substring(0, email.IndexOf("@")));
Console.WriteLine(email.Replace(".", " "));
Console.WriteLine(email.EndsWith(".es"));
Salida
True
12
lucia.garcia
lucia garcia@correo es
True
Método Qué hace
Contains(x) si x está dentro
IndexOf(x) el índice donde aparece x por primera vez (-1 si no está)
Substring(a, n) una parte del texto
Replace(x, y) cada x se reemplaza por y
StartsWith(x), EndsWith(x) si empieza (termina) por x
ToLower() todas las letras en minúscula
Más precisamente, para curiosos

Substring(a, n) toma n caracteres, empezando en el índice a. El segundo argumento es la cantidad de caracteres, no un índice (en Java es al revés: allí es el índice del final). Con un solo argumento toma todo hasta el final:

string date = "2026-10-24";
Console.WriteLine(date.Substring(5, 2));
Console.WriteLine(date.Substring(8));
Salida
10
24

La idea

El texto no cambia

Hay una particularidad que al principio confunde a todo el mundo:

string name = "maria";
name.ToUpper();
Console.WriteLine(name);
name = name.ToUpper();
Console.WriteLine(name);
Salida
maria
MARIA

La segunda línea no hace nada visible. ToUpper() no cambia name. Crea un texto nuevo en mayúsculas y lo devuelve. Nadie lo guarda, y se pierde.

Una vez creado, un texto no se puede cambiar. Se dice que es inmutable (immutable). Cada método que «cambia» un texto en realidad devuelve uno nuevo. Para guardarlo, lo asignas: name = name.ToUpper();.

string name = "maria";
name.ToUpper();
Console.WriteLine(name);
name = name.ToUpper();
Console.WriteLine(name);
Paso a paso, en palabras
  1. name guarda el texto «maria»: 5 caracteres con índices del 0 al 4.
  2. ToUpper() no toca «maria». Crea un texto nuevo, «MARIA».
  3. Nadie guarda el texto nuevo, y se pierde.
  4. name sigue guardando «maria», y eso es lo que se imprime.
  5. Otro texto nuevo, «MARIA», pero ahora = lo guarda en name. El antiguo «maria» se descarta.
  6. Ahora name guarda «MARIA».
Más precisamente, para curiosos
  • Por eso += sobre un texto en un bucle largo es lento: cada vuelta crea un texto nuevo y copia todo lo anterior. Para cientos de miles de añadidos existe StringBuilder, un objeto que sí se puede cambiar. Aquí está con las piezas de un array (vive en System.Text):
string[] parts = { "leche", "pan", "huevos" };
System.Text.StringBuilder list = new System.Text.StringBuilder();
foreach (string part in parts)
{
if (list.Length > 0) list.Append(", ");
list.Append(part);
}
Console.WriteLine(list.ToString());
Salida
leche, pan, huevos

Pruébalo

Encuentra el error

La usuaria escribe su correo con mayúsculas y espacios. El programa debería limpiarlo y dejarla entrar, pero dice «No existe ese usuario.». ¿En qué línea está el error?

Elige la línea con el error.

La idea

El texto en partes

A menudo un texto guarda varias cosas separadas por un signo: productos con una coma, palabras con un espacio. Split lo divide en partes y devuelve un array de textos:

string list = "leche,pan,huevos,queso";
string[] items = list.Split(',');
Console.WriteLine("Productos: " + items.Length);
for (int i = 0; i < items.Length; i++)
{
Console.WriteLine((i + 1) + ". " + items[i]);
}
Salida
Productos: 4
1. leche
2. pan
3. huevos
4. queso

El separador no forma parte de los trozos. A partir de aquí trabajas con un array normal: longitud, índices, un bucle.

Así también se lee una línea entera de números desde el teclado: la divides y conviertes cada parte en un número. Es justo lo que te faltaba en la lección anterior, la de las tablas:

string[] parts = Console.ReadLine().Split(' ');
int sum = 0;
foreach (string p in parts)
{
sum += int.Parse(p);
}
Console.WriteLine(sum);
Entrada
42 38 51 47 60
Salida
238
Más precisamente, para curiosos
  • Dos espacios seguidos dan una parte vacía "" entre ellos. Split(' ', StringSplitOptions.RemoveEmptyEntries) se salta las partes vacías.
  • Puede haber varios separadores: Split(',', ';').
  • Lo contrario de Split es string.Join(", ", items): une las partes con un separador.

Pruébalo

¿Es lo mismo?

En C#, == compara el contenido de los textos, letra por letra. Pero una letra mayúscula y una minúscula son caracteres distintos. La entrada es Madrid:

¿Qué imprimirá el programa?

string city = Console.ReadLine();
Console.WriteLine(city == "Madrid");
Console.WriteLine(city == "madrid");
Console.WriteLine(city.ToLower() == "madrid");
Respuesta

También hay un método para esto: string.Equals(city, "madrid", StringComparison.OrdinalIgnoreCase). En Java, == con texto no compara las letras, y allí se usa equals. Tenlo en cuenta si alguna vez lees código de Java.

Ejercicio

Nombres y palabras

Resuelve los ejercicios en tu editor. El texto se lee del teclado como una línea entera.

1. El nombre al revés. Lee un nombre e imprímelo de atrás hacia delante. Recorres los índices desde el último hasta 0 y añades los caracteres a un texto nuevo.

Entrada
Carmen
Salida
nemraC

2. Número de palabras. Lee una frase y cuenta las palabras. Entre las palabras puede haber más de un espacio, y puede haber espacios al principio y al final. Pista: una palabra empieza donde el carácter no es un espacio y el anterior sí lo es (o no hay ninguno antes).

Entrada
Hoy es un día festivo
Salida
Palabras: 5

3. Palíndromo. Un palíndromo se lee igual de delante hacia atrás que de atrás hacia delante. Los espacios y las mayúsculas no cuentan. Quita los espacios, pon las letras en minúscula y compara el primer carácter con el último, el segundo con el penúltimo, y así sucesivamente.

Entrada
Anita lava la tina
Salida
Es un palíndromo
Entrada
Pan con queso
Salida
No es un palíndromo

Ejercicio

Comprobaciones y conteo

4. Contraseña segura. Pide una contraseña hasta que el usuario escriba una segura: al menos 8 caracteres, al menos una cifra, una mayúscula y una minúscula. Después de cada contraseña débil, di qué se pide. Pista: do-while y una comprobación de cada carácter con char.IsDigit, char.IsUpper, char.IsLower.

Entrada
cafe
cafe2026
Cafe2026
Salida
Contraseña:
Contraseña débil: al menos 8 caracteres, una cifra, una mayúscula y una minúscula.
Contraseña:
Contraseña débil: al menos 8 caracteres, una cifra, una mayúscula y una minúscula.
Contraseña:
Contraseña aceptada.

Más ejercicios

  • Comas en vez de espacios. Lee una frase y reemplaza cada espacio por una coma. Mañana nos vamos a Valencia → Mañana,nos,vamos,a,Valencia.
  • El nombre más largo. Lee nombres separados por comas e imprime el más largo. Ana,Cristina,Pedro → Cristina.
  • Las vocales con asterisco. Reemplaza cada vocal (a, e, i, o, u) por *, sea mayúscula o minúscula. Me gusta leer → M* g*st* l**r.
  • Frecuencia de las letras. Cuenta cuántas veces aparece cada letra en el texto, sin distinguir mayúsculas y minúsculas. Pista: un array de 26 contadores, uno para cada letra de 'a' a 'z' (la ñ y las vocales con tilde quedan fuera de ese rango: de momento puedes no contarlas). El índice de la letra c es c - 'a'. Imprime solo las letras que aparecen.
  • Gráfico de caracteres. Como el ejercicio anterior, pero en lugar del número imprime esa cantidad de asteriscos: a: ****.
  • Cuántas veces cada palabra. Lee una frase y, para cada palabra distinta, imprime cuántas veces aparece. Pista: divídela en palabras y, para cada palabra, comprueba si ya se contó antes en el array.
  • Ordenar por longitud. Lee palabras separadas por espacios e imprímelas de la más corta a la más larga. Ordena el array como ordenabas números, pero compara las longitudes.
  • Número de oraciones. Cuenta las oraciones de un texto: cada una termina con ., ! o ?. Cuidado con ... y ?!: terminan una oración, no tres.
  • Paréntesis equilibrados. Comprueba si los paréntesis de un texto están equilibrados. Con un solo tipo de paréntesis basta un contador: ( suma 1, ) resta 1. El contador nunca debe bajar de 0, y al final debe ser 0. Con tres tipos, (), [], {}, necesitas un array de caracteres donde guardas los paréntesis abiertos, y un contador de hasta dónde está lleno: en un paréntesis de cierre, el último abierto tiene que ser del mismo tipo. {[()]} está equilibrado, ([)] no.

Test

Ponte a prueba

1. ¿Qué da "Casa".Length?
2. ¿Qué hace la línea name.ToUpper(); sola, sin asignación?
3. ¿Qué da "Sevilla" == "sevilla" en C#?
4. ¿Qué diferencia hay entre 'a' y "a"?
5. ¿Qué da "lun,mar,vie".Split(',')?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·