Documentos de Académico
Documentos de Profesional
Documentos de Cultura
08.01 Caracteres
Un caracter es una letra minúscula, mayúscula; un número: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; un signo de puntuación: ¡, !, ¿, ?, .. otros caracteres
como, <, >, %, $ _, @, etc. Para representar el evento de presionar la tecla <enter> ¿podemos usar un caracter?: SÍ; pero no tiene
representación gráfica y es invisible. Hay muchos caracteres invisibles.
En un bit de memoria se guarda 2 estados: 0 y 1; un byte: grupo de 8 bits, puede ser interpretado como número, en bases: 2, 4, 8, 16
(las más usadas)…, también puede ser interpretado como caracter, utilizando la tabla ascii:
Tabla ascii (Un carácter se guarda en un byte = 8 bits)
Número Caracter Se escribe
0 carácter nulo '\0' en un programa; pero cuando se ejecuta, el monitor no muestra nada
…
10 <enter> // caracter invisible '\n' en un programa; pero cuando se ejecuta, el monitor no muestra nada
…
32 Espacio en blanco ' ' en un programa
...
65 A 'A'
66 B 'B'
...
97 a 'a'
98 b 'b'
99 c 'c'
..
255 nbsp
Esta tabla tiene 256 números que son interpretados como 256 caracteres
En un programa, todos los caracteres se pueden escribir como si fueran enteros:
char car = 65; // Equivalente: char car = 'A';
Los visibles se pueden escribir como entero o carácter entre comillas simples:
char car1 = 65, car2 = 'A'; // ambos car1 y car2 tienen como valor la letra ‘A’
otros ejemplos de valores: 'a', '1', '&', '+', ' ' (carácter blanco), etc.
Algunos invisibles se pueden escribir como caracter con escape (/), ejemplo: '/n' representa a <Enter>; también se usa LF (Line Feed, en
inglés).
Los caracteres invisibles no se ven en el monitor, la impresora ni en el teclado, pues no tienen imagen, a veces se ven manchas o signos
raros.
PÁGINA: 1
Salida:
Ingrese 2 caracteres: ab<enter>
a
b
10 // <enter> (carácter invisible) tiene código ascii 10
Explicación: Durante la ejecución, ocurre lo siguiente:
En la línea 06: El computador se detiene y espera el ingreso de: ab<enter>, guarda todo en el buffer, y lee 'a' en cc.
En la línea 07: lee del buffer el carácter 'b' en dd.
En la línea 08: lee del buffer el carácter <enter> en ee.
Ejercicio: Escriba un programa que lea una letra minúscula (la valide como tal) y la convierta en mayúscula (réstele 32).
Una cadena de caracteres es un arreglo de caracteres de una dimensión, que contiene al menos una vez el carácter: '\0' (código ascii =
0, NULL), ejemplo:
char arr[5] = {'a', 'b', '\0','d', '\0' };
arr
a b \0 d \0
Posiciones 0 1 2 3 4
La cadena Inicia en la posición 0, en este ejemplo, con el carácter 'a' y termina cuando encuentra el primer '\0', en este ejemplo, en la
posición 2.
La cadena esta compuesta por: 'a', 'b' y '\0'. Después de esta posición, no se consideran los elementos, en este caso se desperdician:
'd' y '\0'.
Longitud del arreglo arr = 5.
Longitud de la cadena arr: strlen(arr) ≡ 2; el primer carácter '\0' indica el fin de la cadena.
Si asignamos: arr[2] = 'c';
Longitud de la cadena arr cambiará a 4.
char arr1[10] = "hola", arr2[ ] = {'h', 'o', 'l', 'a', '\0'}, arr3[ ]= "Hola";
arr1: es un arreglo de 10 elementos y contiene la cadena “hola” + '\0', longitud de cadena = 4.
arr2: es un arreglo de 5 elementos y contiene la cadena “hola” + '\0', longitud de cadena = 4.
arr3: es un arreglo de 5 elementos y contiene la cadena “Hola” + '\0', longitud de cadena = 4.
Advertencia: Si se omite '\0' como fin de cadena, es un error de lógica SEVERO: el programa compila (no controla el valor de las
variables); pero en tiempo de ejecución se pueden producir errores de resultados o "violación de segmento"; es responsabilidad del
desarrollador garantizar que el arreglo contenga '\0' en algún lugar.
PÁGINA: 3
Leer y escribir cadenas con el formato %s
char arr[20],
scanf("%s", arr); // arr sin & adelante (&arr) porque arr es arreglo y entrega su dirección de inicio.
// descarta los primeros caracteres en blanco, toma solo caracteres distintos de blanco hasta hallar otro blanco:
// ingrese: abc def<enter>
// arr = “abc" incluye '\0', def<enter> queda en el buffer
printf("%s", arr); // escribe toda la cadena, aunque tenga espacios en medio.
Ejemplo:
char arr1[40], arr2[40];
printf("Ingrese dos string: ");
scanf("%s", arr1); // ingrese: aaa bbb ccc<enter> // queda en el buffer: bbb ccc<enter>
scanf("%s", arr2); // lee bbb, queda en el buffer: ccc<enter>
printf("%s %s\n", arr1, arr2);
Salida: aaa bbb
Es responsabilidad del programador no exceder los límites derecho o izquierdo de arreglos y cadenas y el caracter de fin de cadena;
el compilador no reporta error; pero en tiempo de ejecución se producen resultados errados o errores de memoria (violación de
segmento); por ejemplo:
char arr[5] = {'a', 'b', '\0','c', '\0' };
Printf("\n arr[0] = %c arr[1] = %c", arr[0], arr[1]);// Salida: arr[0] = a, arr[1] = b
arr[0] = 'x'; // Asigna 'x' al elemento 0 y se tiene: {'x', 'b', '\0','c', '\0' };
arr[2] = 'z'; // Asigna 'z' al elemento 2 y se tiene: {'x', 'b', 'z','c', '\0' };
arr[4] = 'd'; // Asigna 'd' al elemento 4, arr ya no es cadena sino arreglo que contiene: xbzcd.
PÁGINA: 4
arr[7] = 'z'; // compila, pero en tiempo de ejecución se esta saliendo del arreglo.
arr[-1] = 'r'; // compila, pero en tiempo de ejecución se esta saliendo del arreglo.
Ejemplo: Leer valores de tipo caracter para c1 y c2, según el formato "%c %c" (el primer %c se aparea con c1, el segundo con c2):
#include<iostream>
int main(){
int n;
char c1, c2;
n = scanf("%c %c", &c1, &c2); // teclee: a b n = número de variables leídas
printf("%d: %c %c\n", n, c1, c2);
}
Salida:
2: a b
Si lee caracteres: se leen uno por uno del buffer, por ejemplo para:
scanf("%c", &c1);
El operador puede ingresar:
a<enter> // lee 'a', en el buffer permanece <enter>
a<enter> // lee ' ' (un espacio en blanco), en el buffer permanece a<enter> para ser leido por el siguiente scanf()
Por este motivo, después de leer caracteres, se debe vaciar el buffer con:
while(getchar()!=10); // getchar( ) lee un carácter, 10 es el código ascii de <enter>
Ejemplo:
int n;
n = printf("La vida es bella"); // imprime La vida es bella y asigna a n el número de caracteres escritos: 16
printf("\n%d\n", n);
Salida: La vida es bella
16
printf(": tiene %d caracteres\n", printf("La vida es bella")); // imprime el print ineterno: "La vida es bella" y luego el externo
16 caracteres
Salida: La vida es bella: tiene 16 caracteres
PÁGINA: 5
08.04 Apuntador a Cadena de Caracteres
char cc[] = "abc", *pc = cc;
pc cc
0x…0 a b c \0
0x…0
printf("%s\n", cc); // Salida: abc
printf("%s\n", pc); // Salida: abc
printf("%s\n", pc+1); // Salida: bc
Valores de pcc:
char *pcc= "abc"; // Warning: esta asignación será discontinuada
printf("%p\n", pcc); // Dirección de pcc : 0xf….0
printf("%s\n", pcc); // Cadena apuntada: abc
printf("%s\n", pcc+1); // Cadena apuntada: bc
printf("%c\n",*pcc); // Primer carácter : a
// 08_05.c: Escribir un arreglo de cadenas que contenga el inicio del poema 15 de Neruda
Matriz de caracteres Apuntador a filas de caracteres
#include <iostream>
int main(){
int m=4, n = 60, i=0;
char poema[4][60] =
{"Me gusta cuando callas porque estás como ausente",
"y me oyes desde lejos, Y mi voz no te toca",
"Parece que los ojos se te hubieran volado",
"y parece que un beso te cerrara la boca"};
char *p = poema[0];
for(; i<m; i++) printf("%s\n", poema[i]); for(; i<m; i++, p += n) printf("%s\n", p);
}
Salida:
Me gusta cuando callas porque estás como ausente
y me oyes desde lejos, Y mi voz no te toca
PÁGINA: 6
Parece que los ojos se te hubieran volado
y parece que un beso te cerrara la boca
Entradas: Entradas:
format: cadena de caracteres format: apuntador constante a una cadena de caracteres
ex1, ex2, ... : lista de expresiones a imprimir según format ex1, ex2, ... : lista de expresiones cuyo valor será impreso
según format
Retorno: número de caracteres impresos en el monitor
Ejemplo:
float f = 2.5;
// formato fijo // format dinámico
char format1[ ]= "%.f\n", format2[ ]= "%.2f\n", *pf=format1;
printf(“%f\n”, f); printf(pf, f); // equivalente: printf(format1, f);
pf = format2;
printf(pf, f); // equivalente: printf(format2, f);
Salida:
2.500000 2.500000 2.50
PÁGINA: 8
08.07 Funciones de Salida de Información hacia el Monitor
requiere incluir la librería iostream
Descripción Sintaxis Ejemplo
Imprimir un carácter int putchar(int cc) char cc = 'a';
(sin formato) Entrada: cc: carácter a imprimir. putchar(cc);
Proceso: imprime cc en el monitor. Salida: a
Salida: 1 exitoso, 0 error .
Imprimir,con formato, int printf(const char *format, ex1, ex2, ...) char arr[6] = "ab c";
valores de expresiones Entradas: printf("arr = %s\n", arr);
format: formato para imprimir ex1, ex2, … Salida:
ex1, ex2, ... : lista de expresiones a imprimir. arr = ab c
Proceso: Imprime en el monitor con formato format.
Retorno: Número de caracteres impresos.
Imprimir, sin formato, una int puts(const char *var) char arr[6] = "ab c";
cadena Entrada: var: cadena a imprimir. puts(arr);
Proceso: Imprime var en el monitor. puts("Todo se entendió bien");
Retorno: El número de caracteres impesos + 1. Salida:
ab c
Todo se entendió bien
Imprimir una cadena en un int fputs(const char *cad, FILE *file) char arr[4] = "abc";
archivo de destino Entrada: // imprime en el monitor:
cad: cadena a imprimir. // stdout
file: archivo de salida. fputs(arr, stdout);
Proceso: Escribe var en file. Salida:
Retorno: número de caracteres escritos. abc
Ejemplos
#include<iostream>
int main(){
char datos[6];
printf("Ingrese una cadena de caracteres: ");
scanf("%s", datos); // Ingrese en el teclado: abc
printf("Usted ingresó: %s\n", datos);
}
Salida:
Ingrese una cadena de caracteres: abc
Usted ingresó: abc
PÁGINA: 9
Descripción Sintaxis Ejemplo
Longitud de cadena size_t strlen(char *cad) char arr[ ] = "abc";
Entrada: cad: cadena a operar. printf("%lu\n",strlen(arr));
Proceso: calcula la longitud de cad. Salida: 3
Retorno: longitud de cad sin contar '\0'.
Comparar dos cadenas int strcmp(const char *cad1, const char *cad2) char arr1[ ] = "abcd", arr2[ ] = "xyz";
Entradas: printf("%d\n", strcmp(arr1, arr2));
cad1: cadena a comparar. Salida: < 0
cad2: cadena a comparar.
Proceso: Compara cad1 contra cad2.
Retorno:
< 0 Si cad1 es menor que cad2.
0 Si cad1 es igual a cad2.
> 0 Si cad1 es mayor que cad2.
Buscar un caracter char *strchr(const char *cad, int c) #include<iostream>
dentro de una cadena Entradas: #include<cstring>
cad: cadena en la que se busca. int main(){
c: carácter a buscar. char cad[20] = "Hola amigo", c = 'a', *p;
Proceso: busca a c dentro de *cad. p = strchr(cad, c);
Retorno: apuntador (en la RAM) a la posición de c. if(p) printf("%lu\n", p-cad+1);
La posición de c dentro de cad es: p – arr+1. else printf("No está contenido\n"); // p == NULL
}
Salida: 4
Buscar una cadena char *strstr(const char *cad, const char *cadBus) #include<iostream>
dentro de otra cadena Entradas: #include<cstring>
cad: cadena en la que se busca. int main(){
cadBus: cadena a buscar. char cad[20] = "Hola amigo", bus[] = "la", *p;
Proceso: busca * cadBus dentro de *cad . p = strstr(cad, bus);
Retorno: if(!p) printf("No está contenido\n"); // p == NULL
Si no encuentra la cadena: NULL else printf("%lu\n", p-cad+1);
Si encuentra la cadena: apuntador a la posición de }
inicio de arrBus dentro de cad. La posición de Salida: 3
cadBus dentro de arr es: p – arr+1.
Copiar una cadena de char *strcpy(char *destino, const char *origen) char origen[ ] = "123", destino[ ] = "abcde", *p;
origen sobre otra de Entradas: p = strcpy(destino, origen);
destino destino: cadena de destino. printf("%s %s\n", destino, p);
origen: cadena de origen. Salida: 123 123
Proceso: copia origen en destino.
Retorno: apuntador a la posición de destino.
Copiar n caracteres de char *strncpy(char *destino, const char *origen, char origen[ ] = "123", destino[ ] = "abcde", *p;
origen sobre destino size_t n) p = strncpy(destino, origen, 2);
Entrada: printf("%s %s\n", destino, p);
n = número de caracteres a copiar. Salida: 12cde 12cde
Proceso: copia n caracteres de origen en destino.
Retorno: apuntador a la posición de destino.
Copiar n caracteres a int substring(char *destino, const char *origen, int #include<iostream>
partir de inicio, en inicio, int n) #include<cstring>
origen, sobre destino Entradas: void substring(char *destino, const char *origen, int
origen: cadena de origen. inicio, int n) {
destino: cadena de destino. int i;
inicio = posición de inicio en origen. for(i=0; i<n && inicio+i<strlen(origen); i++)
n = número de caracteres a copiar. destino[i] = origen[inicio+i];
Proceso: copia n caracteres de origen en destino. destino[i] = '\0';
Retorno: longitud de destino, resultado en destino. }
int main(){
char cadena[] = "01/06/98";
char subcadena[3];
substring(subcadena, cadena, 3, 2);
printf("%s\n", subcadena);
}
Salida: 06
Concatenar cad1 con char *strcat(char *cad1, const char *cad2) char arr1[ ] = "abc", arr2[ ] = "1234", *p;
PÁGINA: 10
cad2, el resultado se Entradas: p = strcat(arr1, arr2);
guarda en cad1 cad1: cadena a concatenar. printf("%s %s\n", p, arr1);
cad2: cadena a concatenar. Salida: abc1234 abc1234
Proceso: concatena cad1 con cad2.
Retorno: apuntador a cad1; resultado en cad1.
Concatenar cad1 con char *strncat(char *cad1, const char *cad2, size_t char arr1[ ] = "abc", arr2[ ] = "123", *p;
los n primeros n); p = strncat(arr1, arr2, 2);
caracteres de cad2, el Entradas: printf("%s %s\n", p, arr1);
resultado se guarda en n = número de caracteres, en cad2, a concatenar. Salida: abc12 abc12
cad1 Proceso: concatena cad1 con n caracteres de cad2
Retorno: apuntador a cad1; resultado en cad1.
No es un carácter:
EOF End Of File (fin de archivo) -1 (No ascii) No tiene Al leer contenido de archivos
o de stream
PÁGINA: 11
Problema de manejo de caracteres: Desarrolle un programa en C++ que muestre en pantalla un mensaje con un comportamiento
similar a un letrero de luces de neón, donde las letras en una ventana de m=19 caracteres, se desplazan de izquierda a derecha. El
mensaje será: "El sol de mi tierra" cuya longitud es de n= 19 caracteres. Una vista en un instante de tiempo podría ser:
Ventana: E l S o l d
1 2 3 4 5 6 7 8 9 10
Generar 3 rotaciones.
Indicaciones:
• Cada vez que se imprime una vista de ventana, se debe “dormir” a la computadora por 200 milisegundos para sincronizar su
velocidad con el ojo humano, para ello incluya la librería unistd.h a fin de usar el comando:
usleep(200000);
• Para limpiar la pantalla, incluya la librería cstdlib a fin de usar el comando:
system("clear");
Sugerencia:
1) Alargue la cadena del mensaje para incluir: el amanecer, el día, el atardecer y la noche:
2) Para producir el efecto desplazamiento: imprima n=19 caracteres, avance una posición, imprima m=19 caracteres, avance una
posición …. hasta el final.
// 08_07.c Salida y Puesta del sol
#include <iostream>
#include <cstdlib> // Para ejecutar comandos del terminal como system("clear"), la cual limpia la pantalla
#include <unistd.h> // Para la funcion: usleep(200000), la cual "durme" a la computadora por 200 milisegundos
int main(){
int n = 19, i, j, jmax= n+n+n/2, k;
char mensa[] = " El sol de mi tierra ";
system("clear");
for(i=0; i<3; i++) // Genera 3 rotaciones
for(j=0; j<jmax; j++){
for(k=0; k<n; k++) printf("%c", mensa[j+k]); // ordena imprimir m caracteres al buffer de salida
printf("\n");
usleep(200000);
system("clear");
}
}
Ejemplo: Leer una lista de nombres, crear un arreglo de apuntadores a los nombres, ordenar los apuntadores ascendentemente según
el orden de la lista, ejemplo:
Antes de ordenar los apuntadores Después de ordenar los apuntadores
lista plista (índice) Lista plista (índice)
José Pérez 0xf….00 José Pérez 0xf….20
Carlos Bazán 0xf….20 Carlos Bazán 0xf….00
…
Imprimir lista en modo secuencial (lista en su estado original, sin ordenar):
José Pérez
Carlos Bazán
Imprimir los valores apuntados por plista, recorrer plista en modo secuencial (lista ordenada):
Carlos Bazán
José Pérez
Salida en pantalla:
Pulsa Enter para finalizar...
Nombre y apellidos: José Pérez
Nombre y apellidos: Carlos Bazán
Nombre y apellidos:
PÁGINA: 12
Matriz sin ordenar:
Nombre y Apellidos: José Pérez
Nombre y Apellidos: Carlos Bazán
Matriz ordenada:
Nombre y Apellidos: Carlos Bazán
Nombre y Apellidos: José Pérez
// 08_08.c: ordenar apuntadores a una matriz
#include<iostream>
#include<cstring>
#define MAX 10
#define LONGE 60
int readString(char cc[ ], int n);
int main(){
char lista [MAX][LONGE], *plista[MAX], *pmin; // matriz de datos y arreglo de apuntadores
int n=0, i, j, imin;
// leer
puts("Pulsa Enter para finalizar...");
printf ("Nombre y apellidos: ");
while (readString(lista[n], LONGE) && n<MAX){
plista[n] = lista[n]; // apunta a la fila leída
printf ("Nombre y apellidos: ");
n++;
}
// ordenar el arreglo de apuntadores, método del mínimo
for(i=0; i<n-1; i++){
imin = i; // Hallar elemento mínimo
for(j=i+1; j<n; j++) if(strcmp(lista[i],lista[j]) > 0) imin = j;
if(i<imin){ // poner el mínimo al inicio
pmin = plista[imin];
plista[imin] = plista[i];
plista[i] = pmin;
}
}
// imprimir
printf (" \nMatriz sin ordenar:");
for (i=0;i<n;i++) printf ("\n Nombre y Apellidos: %s", lista[i]);
printf ("\n");
printf ("n\nMatriz ordenada:");
for (i=0;i<n;i++) printf ("\n Nombre y Apellidos: %s", plista[i]);
printf ("\n");
}
int readString(char *cc, int n){
int c, m=0;
n--;
for(;(c=getchar())!=10 && m<n; m++) *cc++= c;
*cc = '\0';
return m;
}
Ejercicio: Modifique el programa anterior utilice funciones para ordenar filas de datos.
PÁGINA: 13
08.09 Funciones para Caracteres
Para utilizar estas funciones requiere incluir:
#include<ctype.h> // biblioteca estándar, contiene macros (una forma de programar funciones) y funciones para validar caracteres:
función Descripción: Valida caracteres
isalnum(char) (A - Z o a – z ) (0 - 9)
isalpha(char) (A - Z o a - z)
isascii(char) 0 - 127 (0x00-0x7F)
iscntrl(char) (0x7F o 0x00-0x1F)
isdigit(char) (0 - 9)
isgraph(char) Imprimibles menos ' '
islower(char) (a - z)
isprint(char) Imprimibles, incluido ' ' // espacio en blanco
ispunct(char) Signos de puntuación
isspace(char) espacio, tab, retorno de línea, cambio de línea, tab vertical, salto de página (0x09 a 0x0D, 0x20).
isupper(char) (A-Z)
isxdigit(char) (0 - 9, A - F, a – f).
tolower(char) Convierte carácter a minúscula
toupper(char) Convierte carácter a mayúscula
PÁGINA: 14
Ejemplo: Parámetros y salida de la función int main()
Para llamar a una función miFun() se pasan argumentos (valores):
n = miFun(4, 3.1);
Al definir a miFun() se definien el tipo de retorno y los parámetros (variables) que reciben los argumentos:
int miFun(int m, float n){ … }
Hasta ahora hemos utilizado la función main( ) sin parámetros de entrada ni salida:
int main(){ … }
Esta es una excepción a la regla; pero podemos cumplirla de ser necesario:
3) El programa:
01 #include<iostream>
02 #include<iostream>
03 using namespace std;
04 int main(){
05 char a = 'a';
06 cout << 'a'; // printf("%c", 'a');
07 cout << a; // printf("%c", a);
08
09 cin >> a; // scanf("%c", &a);
PÁGINA: 15
10 scanf("%c", &a); // cin >> a;
11 scanf("%c", a); // cin >> a;
12 }
Funciona bien desde las líneas 01 a la 09
La línea 10 parece que ejecuta: cin >> a; pero no es así ¿por qué?
La línea 11 daría warning de compilación, ¿por qué?
4) ¿Cuáles son la diferencias entre una cadena, un arreglo de caracteres y un apuntador de caracteres? De un ejemplo usando
printf( )
5) Dado el código:
char saludo[]="Hola", *p=saludo;
while(*p) printf("%s\n", p++);
Explique la segunda línea, ¿cuál es la salida?
6) Dado el código:
char saludo[]={'H', 'o', '\0', 'l','a', '\0'}, *p=saludo;
for(int i=0; i<6; i++) printf("%s\n", p++);
¿Cuál es la salida, por qué?
7) Explique, de dos ejemplos e indique el #include< … > necesario para para usar los siguientes grupos de funciones:
• Entrada de datos desde el teclado
• Salida de información hacia el monitor
• Operación de caracteres
• Operación de cadenas de caracteres
• Para convertir cadenas de caracteres a otras formas de datos
8) Escriba un función que ordene un arreglo numérico y un arreglo de cadenas de caracteres. Utilice apuntadores a funciones.
9) En la teoría del capítulo de Estructuras de repetición vimos el ejemplo de dos amigos A y B que prevenían el alzeimer, para ello
habían escrito un programa que repetía el conteo de 1, 2 y 3, en modo alternativo por los dos amigos:
A B
1
2
3
1
2
3
Ahora desarrollaremos el mismo programa; pero lo haremos más vívido, agregaremos sonidos.
Los archivos de sonido, están incluidos en la carpeta. Para tocarlos se debe instalar los drivers de mp3 en ubuntu: Dentro del programa
fuente están las instrucciones.
Atento: Ver instrucciones del programador
PÁGINA: 16