Char y ASCII
Entiende la relación entre caracteres y números usando la tabla ASCII en C++
¿Cómo la computadora entiende las letras?
La computadora solo entiende números. No sabe qué es una "A", un "5" o un "$". Entonces, ¿cómo maneja texto? Mediante un acuerdo universal: a cada carácter le asignaron un número. Ese acuerdo se llama ASCII (American Standard Code for Information Interchange).
Es como un diccionario secreto: la letra 'A' es el número 65, la 'B' es 66, la 'a' (minúscula) es 97, el dígito '0' es 48, el espacio es 32, etc.
La tabla ASCII
Estos son los caracteres más importantes y sus números:
| Rango | Caracteres | Números ASCII |
|---|---|---|
| Dígitos | '0' a '9' | 48 a 57 |
| Mayúsculas | 'A' a 'Z' | 65 a 90 |
| Minúsculas | 'a' a 'z' | 97 a 122 |
| Espacio | ' ' | 32 |
| Salto de línea | '\n' | 10 |
Dato clave: No necesitas memorizar toda la tabla. Solo recuerda estos patrones:
- Los dígitos van del 48 al 57 (consecutivos).
- Las mayúsculas van del 65 al 90 (consecutivas y en orden alfabético).
- Las minúsculas van del 97 al 122 (consecutivas y en orden alfabético).
- La diferencia entre una mayúscula y su minúscula es 32 (por ejemplo,
'A'= 65 y'a'= 97, diferencia = 32).
char es un número disfrazado de letra
En C++, un char es técnicamente un número entero pequeño (de -128 a 127 o de 0 a 255). Cuando lo imprimes, se muestra como carácter. Cuando haces operaciones matemáticas con él, se comporta como número.
char letra = 'A';
cout << letra << endl; // A (se muestra como carácter)
cout << (int)letra << endl; // 65 (su valor numérico ASCII)
Operaciones con caracteres
Como los char son números, puedes hacer aritmética con ellos:
char a = 'A';
cout << (char)(a + 1) << endl; // B (65 + 1 = 66 = 'B')
cout << (char)(a + 2) << endl; // C (65 + 2 = 67 = 'C')
cout << (char)(a + 25) << endl; // Z (65 + 25 = 90 = 'Z')
Analogía: Imagina que las letras están en casilleros numerados. 'A' está en el casillero 65, 'B' en el 66, etc. Si te piden "avanza 3 casilleros desde la A", llegas a la D (65 + 3 = 68 = 'D').
Trucos útiles con ASCII
1. Convertir un carácter dígito a su valor numérico
Si lees el carácter '7', su valor ASCII es 55, no 7. Para obtener el número real:
char c = '7';
int numero = c - '0'; // 55 - 48 = 7
cout << numero << endl; // 7
¿Por qué funciona? Porque los dígitos son consecutivos en ASCII: '0'=48, '1'=49, '2'=50, ..., '9'=57. Al restar '0' (48), obtienes el valor real del dígito.
'5' - '0' = 53 - 48 = 5
'0' - '0' = 48 - 48 = 0
'9' - '0' = 57 - 48 = 9
2. Convertir entre mayúsculas y minúsculas
La diferencia entre una mayúscula y su minúscula siempre es 32:
char mayuscula = 'A'; // 65
char minuscula = mayuscula + 32; // 65 + 32 = 97 = 'a'
char otra = 'z'; // 122
char otraMay = otra - 32; // 122 - 32 = 90 = 'Z'
También puedes usar las funciones toupper() y tolower():
cout << (char)toupper('a') << endl; // A
cout << (char)tolower('Z') << endl; // z
3. Verificar qué tipo de carácter es
char c;
cin >> c;
// Usando funciones de <cctype>
if (isalpha(c)) cout << "Es una letra" << endl;
if (isdigit(c)) cout << "Es un dígito" << endl;
if (isupper(c)) cout << "Es mayúscula" << endl;
if (islower(c)) cout << "Es minúscula" << endl;
if (isspace(c)) cout << "Es un espacio" << endl;
También puedes hacerlo manualmente con comparaciones:
if (c >= 'A' && c <= 'Z') cout << "Mayúscula" << endl;
if (c >= 'a' && c <= 'z') cout << "Minúscula" << endl;
if (c >= '0' && c <= '9') cout << "Dígito" << endl;
Esto funciona porque los caracteres de cada grupo son consecutivos en ASCII.
4. Posición de una letra en el alfabeto
char c = 'D';
int posicion = c - 'A' + 1; // 68 - 65 + 1 = 4
cout << posicion << endl; // 4 (D es la 4ta letra)
char c2 = 'f';
int pos2 = c2 - 'a' + 1; // 102 - 97 + 1 = 6
cout << pos2 << endl; // 6 (f es la 6ta letra)
5. Obtener la letra en cierta posición
int posicion = 4; // Queremos la 4ta letra
char letra = 'A' + posicion - 1; // 65 + 4 - 1 = 68 = 'D'
cout << letra << endl; // D
Cifrado César: una aplicación clásica
El cifrado César es una técnica de encriptación antigua donde cada letra se reemplaza por otra que está un número fijo de posiciones adelante en el alfabeto.
Por ejemplo, con un desplazamiento de 3:
- A → D
- B → E
- C → F
- ...
- X → A (se "enrolla")
- Y → B
- Z → C
#include <iostream>
using namespace std;
int main() {
string mensaje;
int desplazamiento;
getline(cin, mensaje);
cin >> desplazamiento;
for (int i = 0; i < mensaje.size(); i++) {
char c = mensaje[i];
if (c >= 'A' && c <= 'Z') {
// Cifrar mayúscula
c = 'A' + (c - 'A' + desplazamiento) % 26;
} else if (c >= 'a' && c <= 'z') {
// Cifrar minúscula
c = 'a' + (c - 'a' + desplazamiento) % 26;
}
// Si no es letra, se queda igual
cout << c;
}
cout << endl;
return 0;
}
¿Cómo funciona (c - 'A' + desplazamiento) % 26?
c - 'A'→ Posición de la letra (0-25). Ejemplo: 'D' - 'A' = 3.+ desplazamiento→ Avanzamos. 3 + 3 = 6.% 26→ Si nos pasamos de Z, volvemos al inicio. 6 % 26 = 6.+ 'A'→ Convertimos de vuelta a carácter. 65 + 6 = 71 = 'G'.
El % 26 es la clave: hace que después de Z vuelva a A.
Recorrer el alfabeto
// Imprimir todas las letras mayúsculas
for (char c = 'A'; c <= 'Z'; c++) {
cout << c << " ";
}
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
cout << endl;
// Imprimir todas las minúsculas con su valor ASCII
for (char c = 'a'; c <= 'z'; c++) {
cout << c << "=" << (int)c << " ";
}
// a=97 b=98 c=99 ... z=122
Arreglos indexados por carácter
Un truco muy poderoso: puedes usar un carácter como índice de un arreglo.
Ejemplo: Contar la frecuencia de cada letra en un texto.
#include <iostream>
using namespace std;
int main() {
string texto;
getline(cin, texto);
int frecuencia[256] = {0}; // Un espacio para cada posible carácter ASCII
for (int i = 0; i < texto.size(); i++) {
frecuencia[(int)texto[i]]++;
}
// Mostrar frecuencias de letras que aparecen
for (char c = 'a'; c <= 'z'; c++) {
if (frecuencia[c] > 0) {
cout << c << ": " << frecuencia[c] << '\n';
}
}
return 0;
}
Entrada: hola mundo
Salida:
d: 1
h: 1
l: 1
m: 1
n: 1
o: 2
u: 1
¿Cómo funciona?
- Creamos un arreglo de 256 posiciones (todos los posibles valores ASCII).
- Para cada carácter del texto, incrementamos
frecuencia[valor_ascii]. 'o'tiene valor ASCII 111, así quefrecuencia[111]se incrementa cada vez que encontramos una 'o'.
Este patrón es extremadamente útil en competencias para contar ocurrencias de caracteres.
Problema de ejemplo: ¿Es palíndromo?
Un palíndromo se lee igual al derecho y al revés, ignorando mayúsculas/minúsculas.
#include <iostream>
using namespace std;
int main() {
string s;
cin >> s;
// Convertir todo a minúsculas
for (int i = 0; i < s.size(); i++) {
if (s[i] >= 'A' && s[i] <= 'Z') {
s[i] = s[i] + 32; // Convertir a minúscula
}
}
// Verificar palíndromo
bool esPalindromo = true;
int n = s.size();
for (int i = 0; i < n / 2; i++) {
if (s[i] != s[n - 1 - i]) {
esPalindromo = false;
break;
}
}
if (esPalindromo) cout << "Si" << endl;
else cout << "No" << endl;
return 0;
}
Ejercicio de práctica
Lee una cadena de texto y cuenta cuántas vocales y cuántas consonantes tiene (solo considera letras, ignora otros caracteres). Trata mayúsculas y minúsculas por igual.
Entrada: Hola Mundo 123
Salida:
Vocales: 4
Consonantes: 5
Ver solución
#include <iostream>
using namespace std;
int main() {
string texto;
getline(cin, texto);
int vocales = 0, consonantes = 0;
for (int i = 0; i < texto.size(); i++) {
char c = texto[i];
// Convertir a minúscula si es mayúscula
if (c >= 'A' && c <= 'Z') {
c = c + 32;
}
// Solo procesar si es letra
if (c >= 'a' && c <= 'z') {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
vocales++;
} else {
consonantes++;
}
}
}
cout << "Vocales: " << vocales << '\n';
cout << "Consonantes: " << consonantes << '\n';
return 0;
}
Siguiente paso
Con char y ASCII dominados, estás listo para avanzar a las Estructuras de Control donde aprenderás a tomar decisiones y repetir acciones en tu programa.
