Vous êtes sur la page 1sur 30

MP 11 Fundamentos Programación UF 02 Diseño Modular

MÓDULO 6 FUNDAMENTOS PROGRAMACIÓN EN C, C++.

Modular MÓDULO 6 – FUNDAMENTOS PROGRAMACIÓN EN C, C++. OBJETIVOS. Seguiremos en este módulo con los

OBJETIVOS.

Seguiremos en este módulo con los punteros y vectores, concretamente veremos un caso particular de vectores, los vectores de caracteres o cadenas de caracteres.

Concretamente, los aspectos que tratará este módulo son:

¿Qué son las cadenas de caracteres? ¿Cómo se almacena en la memoria?

Valor inicial de una cadena de caracteres.

Funciones de cadena. Entrada y Salida:

scanf(), gets() y fgets();

printf(), puts() y fputs().

Otras funciones de tratamiento de caracteres:

strlen(), strcpy(), strncpy(), strcat(), strncat(), strcmp(), strncmp(),stricmp(), _strnicmp(), strchr(), strrchr(), strstr(), strpbrk(), isalpha(), isupper(), islower(), isdigit(), isalnum(), e isspace().

, islower() , isdigit() , isalnum() , e isspace() . MP 11 – UF 02 –

MP 11 UF 02 Módulo 4 Fundamentos Programación.

Página 1

, isdigit() , isalnum() , e isspace() . MP 11 – UF 02 – Módulo 4

1.

RESUMEN TEÓRICO.

1.1. CADENAS DE CARACTERES.

Una cadena de caracteres es un vector de datos del tipo char que acaba en un carácter NULL ('\0'). Por esta razón se deben declarar vectores de caracteres con un carácter más que la cadena más larga que queramos almacenar.

Por ejemplo, si queremos un vector que almacene el mensaje Esto deberemos declarar un vector de la siguiente forma: char str[19].

es una cadena,

1.1.1. VALOR INICIAL DE UNA CADENA DE CARACTERES.

Podemos

diferentes:

poner valores iniciales en

una cadena de

caracteres

de

dos

formas

a) De la forma estándar de los vectores, tal y como se ha visto en el módulo anterior. Cada carácter va cerrando entre comillas sencillas y los caracteres separados por

comillas: char str[5] = {'h','o','l','a','\0'};

b) De la forma abreviada: char str[5] = "hola";

De esta forma, todos los caracteres se escriben juntos, cerrados por dobles comillas y sin poner el carácter '\0' de fin de cadena que se pone automáticamente.

En cualquiera de las dos formas se puede omitir la dimensión; es decir, es válido

tanto: char str[] = {'h','o','l','a','\0'};' como: char str[] = "hola";

En los dos casos, el compilador de C creará automáticamente un vector de cinco elementos de caracteres.

1.1.2. FUNCIONES DE CADENAS. ENTRADA Y SALIDA.

La introducción de una cadena en un programa tiene dos fases:

1)

La primera prepara el espacio de memoria suficiente para su almacenamiento, esto se consigue con su declaración.

2)

La segunda fase consiste en usar una función para capturar la cadena. Para capturar cadenas directamente del teclado se pueden utilizar tres funciones, la declaración de las cuales están en el archivo estándar stdio.h. Una de estas funciones ya se ha visto con anterioridad, se trata de la función scanf(). Las otras funciones son gets() y fgets().

La función gets() tiene el siguiente prototipo: char *gets(char *var);. Esta función recibe caracteres de entrada estándar (el teclado) y asigna los caracteres al vector de caracteres var[]. Cuando se presiona la tecla INTRO al finalizar la cadena, se envía un carácter de nueva línea que es traducido por esta función por un carácter nulo de fin de cadena. Es importante remarcar que esta función no realiza la comprobación que la cadena leída tenga un tamaño igual o inferior al tamaño reservado para almacenar la variable.

Si se utiliza esta función, el compilador nos dará un error leve: Warning: the

'gets' function is dangerous and should not be used. La biblioteca GNU la incluye

por un tema de compatibilidad, pero es mejor utilizar otras funciones ya que como se ha comentado antes no contiene ninguna precaución para no desbordar la longitud de la cadena.

precaución para no desbordar la longitud de la cadena. MP 11 – UF 01 – Módulo

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 2

para no desbordar la longitud de la cadena. MP 11 – UF 01 – Módulo 6

Otra función parecida que permite esta comprobación es la función fgets(). Tiene el

siguiente prototipo: char *fgets(char *var, int n, FILE *flux);.

Cuando se utiliza esta función para leer cadenas del teclado, el tercer argumento será stdin, que corresponde a la entrada estándar. En el último módulo se tratará con más detalle las entradas y salidas.

Esta última función tiene la ventaja que se puede garantizar un número máximo de caracteres. La lectura se realiza hasta que se encuentra un carácter de nueva línea (con INTRO) o bien hasta que se lean n-1 caracteres (incluyendo el carácter de nueva línea).

La función gets() reemplaza el carácter de nueva línea leído por teclado por el carácter NULL ('\0'), en cambio la función fgets() añade al carácter de nueva línea el carácter NULL ('\0'). Ambas funciones retornan un puntero a la cadena leída o escrita, o bien el puntero NULL si ha habido un error.

Para que se muestre el contenido de una cadena por el teclado se utilizan las tres funciones asociadas respectivamente a scanf(), gets() y fgets(), se trata de printf(), puts() y fputs(). La primera de ellas ya la hemos visto y tratado con anterioridad.

La función puts() escribe el contenido de su argumento por pantalla reemplazando el carácter NULL por el carácter de nueva línea; en cambio, la función fputs() no realiza ningún reemplazo.

Los prototipos de las dos funciones son: int puts (const char *cadena);

int fputs (const char *cadena, FILE *flux);

En el caso de la función fputs(), si la salida es la salida estándar, se reemplaza el tercer argumento por stdout.

1.1.3. OTRAS FUNCIONES DE TRATAMIENTO DE CADENAS.

Las funciones estándar más importantes que permiten trabajar con cadenas de caracteres y que están definidas en el archivo string.h son las siguientes:

int strlen(const char *cadena) Retorna el número de caracteres de la cadena, sin contar el carácter '\0'.

char *strcpy( char *cadestino, const char *cadfuente); Copia el

contenido de la cadena cadfuente en la cadena cadestino. Se debe tener en cuenta que esta función es diferente a la asignación: *cadestino=*cadfuente. Esta última sentencia sólo pondría el primer carácter de cadfuente a cadestino, además, no pone ningún carácter de fin de cadena. En esta función se debe tener en cuenta que la cadena cadfuente no sea mayor que la cadena cadestino. Esta función elimina el contenido previo de la cadena cadestino.

char *strncpy( char *cadestino, const char *cadfuente, int n);

Copia el contenido de los n primeros caracteres de cadfuente en cadestino. Si n es más pequeño o igual que la longitud de la cadena cadfuente no se añade ningún carácter NULL de final de cadena. Si n es más grande que la longitud de la cadena cadfuente, la cadena cadestino se llena de caracteres NULL hasta la longitud n. Esta función, como la anterior, no realiza comprobación de longitud y, por tanto, el comportamiento puede ser desastroso si la longitud de la cadena cadfuente y n son más grandes que la longitud de la cadena cadestino.

son más grandes que la longitud de la cadena cadestino . MP 11 – UF 01

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 3

que la longitud de la cadena cadestino . MP 11 – UF 01 – Módulo 6

char *strcat(char *cadestino, const char *cadfuente); Añade la

cadena cadfuente al final de la cadena cadestino. La cadena cadfuente no cambia su contenido.

char *strncat(char *cadestino, const char *cadfuente, int n);

Añade n caracteres de la cadena cadfuente al final de la cadena cadestino. En esta función y en la anterior el primer carácter añadido sustituye al carácter fin de cadena anterior. Este carácter se añade al final.

int strcmp(char *cad1, const char *cad2); Esta función compara las

cadenas cad1 y cad2. Retorna un '0' si coinciden y un número diferente de '0' si no coinciden. La comparación se realiza carácter a carácter hasta encontrar un carácter que no coincide o con el carácter fin de cadena.

int strncmp(char *cad1, const char *cad2, int n); Compara los n

primeros caracteres de las cadenas cad1 y cad2. La comparación se realiza carácter a carácter hasta encontrar un carácter que no coincide o con el carácter fin de cadena.

int _stricmp(char *cad1, const char *cad2); int _strincmp(char *cad1, const char *cad2, int n);

Estas dos funciones son similares a las dos anteriores, pero con la diferencia que en la comparación no distinguen entre mayúsculas y minúsculas. El símbolo '_' indica que estas funciones no corresponden al estándar ANSI, no obstante, también se pueden utilizar en Visual C++ sin este carácter.

char *strchr(const char *cad, int c); Esta función retorna un puntero

a la primera ocurrencia del carácter c en la cadena cad. Si este carácter no está se retorna un NULL.

char *strrchr(const char *cad, int c); Esta función retorna un

puntero a la última ocurrencia del carácter c en la cadena cad. Si este carácter no está se retorna un NULL.

char *strstr(const char *cad, const char *subcad); Esta función

retorna un puntero a la primera ocurrencia de la subcadena subcad en la cadena cad

o bien un puntero a NULL si no se encuentra.

char *strpbrk(const char *cad, const char *subcad); Esta función

retorna un puntero a la primera ocurrencia de cualquiera de los caracteres de subcad en la cadena cad o bien un puntero a NULL.

Además de estas funciones, hay otras que pueden ser útiles para el tratamiento de cadenas. Las declaraciones de estas funciones están en el fichero cabecera ctype.h:

int isalpha(int c); Esta función retorna un valor diferente de '0' si c es una letra y '0' si no lo es.

int isupper(int c); Esta función retorna un valor diferente de '0' si c es una letra mayúscula y '0' si no lo es.

int islower(int c); Esta función retorna un valor diferente de '0' si c es una letra minúscula y '0' si no lo es.

int isdigit(int c); Esta función retorna un valor diferente de '0' si c es un dígito y '0' si no lo es.

int isalnum(int c); Esta función retorna un valor diferente de '0' si c es una letra o un dígito y '0' si no lo es.

int isspace(int c); Esta función retorna un valor diferente de '0' si c es un espacio, un tabulador o el carácter de nueva línea y '0' si no es nada de esto.

de nueva línea y '0' si no es nada de esto. MP 11 – UF 01

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 4

línea y '0' si no es nada de esto. MP 11 – UF 01 – Módulo

2.

PRÁCTICA 1:

INVERSIÓN DE UNA PALABRA.

Como primera práctica de cadenas de caracteres, comenzaremos a manipular una cadena carácter a carácter para poder invertirla.

2.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo C denominado m6p01.c y se escribirá el siguiente código:

//m6p01.cc - INVERTIR LA POSICIÓN DE LAS LETRAS DE UNA PALABRA -

#include <stdio.h> #include <stdlib.h>

int main(){

char palabra[21]; int i; system("clear"); printf("Teclee una palabra:\n"); scanf("%s", palabra);

i = 0;

while(palabra[i++] != '\0');

i--; printf("%s tiene %d letras.\n", palabra, i); printf("%s escrita al revés: ", palabra); while (i >= 0) printf("%c", palabra[i--]); printf("\n"); return 0;

}

2.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

return 0; } 2.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 –
return 0; } 2.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 5

} 2.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 – Módulo 6

2.3.

EXPLICACIÓN DEL PROGRAMA.

En primer lugar, se declara una variable char y una variable de cadena palabra[21]. Esta variable es un vector de caracteres. Se reserva espacio para 21 caracteres (21 octetos). La lectura de la palabra se realiza con la función scanf(). La forma de obtener el número de caracteres es una alternativa curiosa a la función strlen(), es la línea:

while(palabra[i++] != '\0');

Este bucle vacío se ejecuta hasta que se encuentre el carácter '\0'. Aunque el cuerpo del bucle está vacío, cada vez que se comprueba la condición, se incrementa el valor de la variable i en una unidad, por tanto, cuando se sale del bucle porque se ha encontrado el carácter de fin de cadena ('\0'), el valor de la variable i es igual a la longitud de la cadena más una unidad (más una unidad ya que cuando se encuentra con el carácter fin de cadena todavía incrementa en 1 el valor de i).

Es evidente que esta línea se podría sustituir por: i=strlen(palabra); (para esta primera línea sería necesario el archivo cabecera string.h).

La línea que imprime en pantalla la palabra al revés es:

while (i >= 0) printf("%c", palabra[i--]);

Es un bucle formado por una única sentencia, pero, cada vez que se escribe uno de los caracteres de la palabra (comenzando por el último) se decrementa el valor de la variable en 1.

Si en lugar de leer una palabra sólo, se puede leer una frase, se debe modificar el programa anterior ya que la función scanf() solo lee la primera palabra de la frase, la lectura se detiene cuando se llega al primer carácter blanco.

se detiene cuando se llega al primer carácter blanco. MP 11 – UF 01 – Módulo

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 6

cuando se llega al primer carácter blanco. MP 11 – UF 01 – Módulo 6 –

3.

PRÁCTICA 2:

VECTORES PUNTEROS A CADENAS DE CARACTERES.

En esta práctica veremos que se puede definir u vector de cadenas de caracteres; es decir, un vector de punteros de caracteres.

3.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo C++ denominado m6p02.cc con el siguiente código:

//m6p02.cc - VECTORES A CADENAS DE CARACTERES -

#include <iostream> #include <stdlib.h>

using namespace std;

char *nombre_mes(int n);

int main(){

int mes;

}

system("clear");

cout<<"Escribe el nombre del mes "; cin>>mes;

cout << "El mes es return 0;

"<<nombre_mes(mes)<<endl;

char *nombre_mes(int n){ char *nombre[]={"Mes no valido","Enero","Febrero","Marzo","Abril", "Mayo","Junio","Julio","Agosto","Septiembre", "Octubre","Noviembre","Diciembre"

}

return ( n < 1 || n > 12 ) ? nombre[0]:nombre[n] ;

}

3.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

; } 3.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 – Módulo
; } 3.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 – Módulo

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 7

} 3.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 – Módulo 6

3.3.

EXPLICACIÓN DEL PROGRAMA.

Los vectores también pueden contener punteros. En este caso cada posición de este vector es un puntero a la primera posición de la cadena de caracteres. El vector *nombre es un vector de punteros a cadenas:

char *nombre_mes(int n){ char *nombre[]={"Mes no valido","Enero","Febrero","Marzo","Abril", "Mayo","Junio","Julio","Agosto","Septiembre", "Octubre","Noviembre","Diciembre"

}

Este vector puede representarse como:

} Este vector puede representarse como: La función nombre_mes () retorna una cadena (un puntero a

La función nombre_mes() retorna una cadena (un puntero a un vector de caracteres). La cadena retornada se calcula en la siguiente línea:

return ( n < 1 || n > 12 ) ? nombre[0]:nombre[n] ;

Si el argumento no es un número comprendido entre 1 y 12 el resultado es nombre[0]; es decir, la cadena "Mes no válido", en caso contrario retorna la cadena nombre[n].

", en caso contrario retorna la cadena nombre[n] . MP 11 – UF 01 – Módulo

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 8

caso contrario retorna la cadena nombre[n] . MP 11 – UF 01 – Módulo 6 –

4.

PRÁCTICA 3:

INTRODUCCIÓN A LA CRIPTOLOGÍA. EL MÉTODO DE SUSTITUCIÓN DE JULIO CÉSAR.

En esta práctica aprenderemos una aplicación clásica y sencilla de la manipulación de cadenas de caracteres.

4.1. DESARROLLO DE LA PRÁCTICA.

Posiblemente, el primer sistema de encriptación de mensajes tuvo su origen en tiempos de Julio César, cuando la escritura en latín comenzó a ser popular. Este sistema, realizado de forma sencilla, consistía en sustituir una letra por la situada tres posiciones a la derecha, suponiendo el alfabeto ordenado en su orden natural.

Por ejemplo, la letra A se transforma en D y la B en E. En este método podemos imaginar que tras la letra Z se encuentra la A, por tanto, la X se transforma en A, la Y en B y la Z en C.

Generalizando, se denomina método de Julio César al método de encriptación que consiste en sustituir una letra por la situada n lugares a la derecha, suponiendo el alfabeto ordenado en su orden natural.

Podemos, para simplificar, pensar en el alfabeto inglés de 26 caracteres, y sólo las letras minúsculas. Los códigos ASCII de estos 26 símbolos son los que van del 97 al 122.

El algoritmo para sustituir una letra por otra es: c (c-97+n)%26+97, donde c es el código ASCII del carácter a sustituir.

En esta práctica haremos un programa que permita encriptar y desencriptar mensajes, de hecho, si un mensaje se ha encriptado usando el código n, el código 26-n permitirá desencriptarlo con el mismo algoritmo.

Crearemos un nuevo archivo del tipo C++ denominado m6p03.cc con el siguiente código:

//m5p03.cc - MÉTODO JULIO CÉSAR -

#include <stdio.h> #include <stdlib.h> #include <ctype.h>

char *Cesar(char *mensaje, int n);

int main(){ char mensaje[100]; int codigo;

system("clear");

printf("Introduce el mensaje

fgets(mensaje,80,stdin);

\n");

printf("\n\n Introduce el codigo (0-25) scanf("%d", &codigo);

\n");

printf("\nEl mensaje modificado es:\n%s\n\n", Cesar(mensaje, codigo)); return 0;

es:\n%s\n\n", Cesar(mensaje, codigo)); return 0; } MP 11 – UF 01 – Módulo 6 – Fundamentos

}

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 9

Cesar(mensaje, codigo)); return 0; } MP 11 – UF 01 – Módulo 6 – Fundamentos Programación.

char *Cesar(char*mensaje, int n){ int i=0; while(mensaje[i]){ if (mensaje[i]!=' ')

mensaje[i]=(tolower(mensaje[i])-97+n)%26+97;

i++;

}

return mensaje;

}

4.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

mensaje; } 4.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. 4.3. EXPLICACIÓN DEL PROGRAMA. En esta práctica,

4.3. EXPLICACIÓN DEL PROGRAMA.

En esta práctica, la introducción de la cadena por teclado se realiza con la función fgets().

La función Cesar() recibe como argumento un puntero a la cadena Mensaje y un entero que corresponde al código utilizado para la encriptación (o desencriptación) del mensaje. Esta función se basa en el siguiente bucle:

while(mensaje[i]){ if (mensaje[i]!=' ')

mensaje[i]=(tolower(mensaje[i])-97+n)%26+97;

i++;

}

La condición de la sentencia while es una condición típica de C (es decir, que no parece una condición), la cual es una carácter de la cadena, será verdadera hasta que se encuentre el carácter fin de cadena ('\0), momento en el cual saldrá del bucle.

Para cada carácter de la cadena se comprueba si es el espacio en blanco. Este carácter se modifica, los otros sí. La función tolower() hace que todos los caracteres de la cadena se conviertan en letras minúsculas.

El cuerpo del bucle es la transformación antes mencionada. Debemos recordar que el operador % es el resto de la división entera, por tanto, la expresión: (mensaje[i])-97+n)%26+97; dará un entero entre 97 y 97+25.

(mensaje[i])-97+n)%26+97; dará un entero entre 97 y 97+25. MP 11 – UF 01 – Módulo 6

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 10

dará un entero entre 97 y 97+25. MP 11 – UF 01 – Módulo 6 –

5.

PRÁCTICA 4:

CÁLCULO DEL NÚMERO DE LÍNEAS, PALABRAS Y CARACTERES.

En esta práctica aprenderemos más sobre la manipulación de cadenas de caracteres. Veremos también como introducir una cadena de más de una línea.

5.1. DESARROLLO DE LA PRÁCTICA.

El programa calculará el número de líneas, palabras y caracteres que se introduzcan por el teclado e imprimirá los resultados para la salida estándar (pantalla). Para detectar líneas debe buscar el carácter fin de línea '\n'. Para detectar palabras se define una variable Estado que recuerda si estaba leyendo una palabra cuando encuentra un espacio en blanco, un fin de línea o un tabulador ('\t').

Crearemos un nuevo archivo C denominado m6p04.c con el siguiente código:

//m6p04.c - CUENTA LÍNEAS, PALABRAS Y CARACTERES. -

#include <stdio.h> #include <ctype.h>

#define DENTRO 1 // Dentro de una palabra. #define FUERA 0 // Fuera de una palabra.

int main(){ int c, nl, np, nc, Estado;

Estado = FUERA; np = nc = 0; nl = 1;

printf("Introduzca un texto, si quiere, de más de una línea\n"); printf("Presionar CTRL+D para finalizar\n\n");

while ((c = getchar()) != EOF)

{

 

++nc; if (c == '\n') ++nl;

if (isspace(c)) Estado = FUERA; else if (Estado == FUERA)

{

Estado = DENTRO;

++np;

}

}

printf("\n\n líneas:%d\n palabras:%d\n caracteres:%d\n",--nl,np,nc); return 0;

palabras:%d\n caracteres:%d\n",--nl,np,nc); return 0; } MP 11 – UF 01 – Módulo 6 – Fundamentos

}

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 11

return 0; } MP 11 – UF 01 – Módulo 6 – Fundamentos Programación. Página 11

5.2.

CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

5.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. 5.3. EXPLICACIÓN DEL PROGRAMA. Las variables nl , np

5.3. EXPLICACIÓN DEL PROGRAMA.

Las variables nl, np y nc se encargarán respectivamente de almacenar el número de líneas, de palabras y de caracteres. La primera de las variables es inicializada a 1 y el resto a 0.

La lectura del texto se realiza con la sentencia: while

((c = getchar()) != EOF){

que lee caracteres hasta encontrar un carácter EOF (End Of Line), que se crea con las teclas

CTRL+D.

El cuerpo de la sentencia while se puede dividir en tres partes. Cada una de estas partes se encargarán de contar los caracteres, las líneas y las palabras:

++nc; if (c == '\n') ++nl; if (isspace(c)) Estado = FUERA; else if (Estado == FUERA)

{

Estado = DENTRO; ++np;

}

Cada vez que se lee un carácter se incrementa la variable nc en 1. Si el carácter es el carácter de nueva línea: ('\n'), se incrementa la variable nl en 1.

La parte que cuenta palabras es algo más sofisticada. Inicialmente, la variable Estado está inicializada en FUERA (macro definida al inicio). Si el carácter leído es un carácter de separación de palabras (espacio en blanco, tabulador o retorno de línea) se asigna el valor FUERA a la variable Estado, en caso contrario, se asigna el valor DENTRO. Esta comprobación se realiza con la función isspace(). La variable np se incrementa cuando la variable Estado pasa de FUERA a DENTRO.

cuando la variable Estado pasa de FUERA a DENTRO . MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 12

Estado pasa de FUERA a DENTRO . MP 11 – UF 01 – Módulo 6 –

6.

PRÁCTICA 5:

INSERTAR UN TEXTO.

En esta práctica implementaremos la función de insertar una cadena en otra.

6.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo del tipo C denominado m6p05.c con el siguiente código:

// m6p05.c - INSERTAR UNA CADENA EN OTRA -

#include <stdio.h> #include <string.h>

char *insertar (char*, int ,char*); int main(){ char cad1[200]; char cad2[20]; int n;

printf("\n Introducir la primera cadena =

");

fgets(cad1,200,stdin);

printf("\n Introducir la segunda cadena =

");

}

scanf("%[^\n]",cad2);

printf("\n Posicion =

printf("\n Primera cadena = %s\n",insertar(cad1,n,cad2)); return 0;

");

scanf("%d",&n);

char *insetar (char *cad1, int n, char *cad2){ int i,pos; i=n;

pos=strlen(cad2);

for (i=strlen(cad1);i>=n;i--) cad1[i+pos]=cad1[i]; for (i=0;i<pos;i++) cad1[n+i]=cad2[i]; return cad1;

}

6.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

return cad1; } 6.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 –
return cad1; } 6.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 13

6.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 – Módulo 6 –

6.3.

EXPLICACIÓN DEL PROGRAMA.

En este programa se implementa la función insertar que tiene el protocolo:

char *insetar (char *cad1, int n, char *cad2)

Esta función inserta una cadena en una posición determinada de otra cadena. Por ejemplo, si la cadena cad1 contiene: "Aixó és una prova" y la cadena cad2 contiene: "no ", la función insetar(cad2, 5, cad1) hará que cad1 sea: "Aixó no és una prova":

hará que cad1 sea: "Aixó no és una prova": La inserción se realiza en dos fases:

La inserción se realiza en dos fases: la primera fase desplaza los caracteres de cad1 que hay después de la posición n un número de posiciones igual al tamaño de la cadena cad2 (pos)

for (i=strlen(cad1);i>=n;i--) cad1[i+pos]=cad1[i];

La segunda fase reemplaza los caracteres de las posiciones n y siguientes de la cadena cad1

por la cadena cad2 for (i=0;i<pos;i++) cad1[n+i]=cad2[i];.

En la siguiente figura se muestra las dos fases de esta inserción:

figura se muestra las dos fases de esta inserción: Esta función no comprueba los límites. En

Esta función no comprueba los límites. En el caso que la suma de los tamaños de cad1 y cad2 fuese superior al tamaño máximo de cad1 se produciría un error en tiempos de ejecución.

de cad1 se produciría un error en tiempos de ejecución. MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 14

un error en tiempos de ejecución. MP 11 – UF 01 – Módulo 6 – Fundamentos

7.

PRÁCTICA 6:

CONTAR EL NÚMERO DE VECES QUE UNA CADENA ESTÁ CONTENIDA EN OTRA.

En esta práctica utilizaremos la función strstr() de la librería estándar para contar el número de veces que una cadena aparece en otra cadena.

7.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo en C denominado m6p06.c con el siguiente código:

// m6p06.c - CONTAR SUBCADENAS - // Este programa cuenta el número de veces que una cadena está contenida en otra.

#include <stdio.h> #include <string.h> #include <stdlib.h>

int Conteo(char*, char*);

int main (void){ char Texto[200]; char Subcadena[10];

system("clear");

printf("Introduzca el texto:\n");

fgets(Texto,200,stdin);

printf("Introduzca la Subcadena:\n"); scanf("%[^\n]",Subcadena);

printf("%d veces\n", Conteo(Texto, Subcadena)); return 0;

}

int Conteo(char *Texto, char *Subcadena

{

char *p;

int Ct=0;

P=Texto;

while(P){ //Mientras haya texto, realizará la operación siguiente. P=strstr(P, Subcadena);

realizará la operación siguiente. P=strstr(P, Subcadena); if(P) {   P=P+strlen(Subcadena); Ct++; } }

if(P)

{

 

P=P+strlen(Subcadena);

Ct++;

}

}

return Ct;

}

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 15

Ct++; } } return Ct; } MP 11 – UF 01 – Módulo 6 – Fundamentos

7.2.

CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

7.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. 7.3. EXPLICACIÓN DEL PROGRAMA. En este programa dispondremos de

7.3. EXPLICACIÓN DEL PROGRAMA.

En este programa dispondremos de dos cadenas entradas por teclado con la función gets(); es decir, cadenas sin caracteres de retorno de línea. Las cadenas son: Texto[] de un máximo de 199 caracteres, y Subcadena[] de un máximo de 9 caracteres (hay que recordar que se reserva uno para el carácter fin de cadena '\0'.

retornará un entero que será el número de veces que la cadena

La función Conteo()

Subcadena se encuentra en la cadena Texto.

La función Conteo() declara un puntero P, al cual se le asigna la función strstr(). Esta función retorna un puntero a la primera aparición de la Subcadena en el texto. Si la Subcadena no aparece en el texto, la función strstr() retorna un puntero NULL, cosa que hace que se salga del bucle.

Si la función strstr() no retorna un puntero NULL quiere decir que ha encontrado una

aparición de la Subcadena. En este momento se hace:

P=P+strlen(Subcadena);

Ct=++;

De esta forma, el puntero P apuntará al texto justo a continuación de la Subcadena, para poder aplicar de nuevo la función strstr() al resto de la cadena. También se debe incrementar en 1 el contador. Cuando sale del bucle, esta variable Ct contendrá el número de veces que la Subcadena aparece en el texto.

el número de veces que la Subcadena aparece en el texto. MP 11 – UF 01

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 16

veces que la Subcadena aparece en el texto. MP 11 – UF 01 – Módulo 6

8.

PRÁCTICA 7:

REEMPLAZAR PARTE DE UNA CADENA POR OTRA.

En esta práctica implementaremos una útil función de reemplazo de una parte de una cadena por otra.

8.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo del tipo C++ denominado m6p07.cc con el siguiente código:

//m6p07.cc - REEMPLAZAR SUBCADENA -

#include <stdio.h> #include <string.h> #include <stdlib.h>

char *Reemplazar(char*, char*, int N);

int main (){ char Texto[200]; char Subcadena[10]; int N;

system("clear");

printf("Introduzca el texto:\n");

fgets(Texto,200,stdin);

printf("Introduzca la subcadena:\n"); scanf("%[^\n]",Subcadena);

printf("Posicion

scanf("%d",&N);

\n");

Reemplazar(Texto, Subcadena, N); printf("texto=%s\n\n",Texto);

return 0;

}

char *Reemplazar(char *Texto, char *Subcadena, int N)

{

 

char *P; unsigned int Ct; P = Texto + N;

for(Ct=0;Ct<strlen(Subcadena);Ct++) *(P+Ct)=Subcadena[Ct];

return Texto;

}

*(P+Ct)=Subcadena[Ct]; return Texto; } MP 11 – UF 01 – Módulo 6 – Fundamentos

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 17

return Texto; } MP 11 – UF 01 – Módulo 6 – Fundamentos Programación. Página 17

8.2.

CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

8.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. 8.3. EXPLICACIÓN DEL PROGRAMA. En este programa se implementa

8.3. EXPLICACIÓN DEL PROGRAMA.

En este programa se implementa la función Reemplazar que tiene el protocolo:

char *Reemplazar(char *Texto, char *Subcadena, int N)

Es por tanto, una función que retorna una cadena (la misma cadena Texto) y reemplaza caracteres de la cadena Texto por la cadena Subcadena a partir de la posición N. Por ejemplo: si Texto contiene la cadena "Això és una prova" y Subcadena contiene "dos", la función Reemplazar(Texto, Subcadena, 8) cambiará el contenido de texto por: "Això és dos prova":

el contenido de texto por: "Això és dos prova": En la línea de código que realiza

En la línea de código que realiza este reemplazo, P es un puntero que apunta a la primera posición del texto que debe reemplazarse:

for(Ct=0;Ct<strlen(Subcadena);Ct++) *(P+Ct)=Subcadena[Ct];

Debe observarse que esta función no realiza comprobación de límites. Si la Subcadena o el valor de N son demasiado grandes puede sobrescribirse parte de la memoria no reservada para la cadena Texto.

parte de la memoria no reservada para la cadena Texto . MP 11 – UF 01

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 18

memoria no reservada para la cadena Texto . MP 11 – UF 01 – Módulo 6

9.

PRÁCTICA 8:

ELIMINAR PRIMERA APARICIÓN DE UNA SUBCADENA

En esta práctica implementaremos una función ligeramente más complicada que la función de la práctica anterior, ya que se deben mover los caracteres de su lugar.

9.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo de tipo C denominado m6p08.c con el siguiente código:

//m6p08.c - ELIMINACIÓN DE LA PRIMERA APARICIÓN DE UNA SUBCADENA -

- ELIMINACIÓN DE LA PRIMERA APARICIÓN DE UNA SUBCADENA - #include <stdio.h> #include <stdlib.h>

#include <stdio.h> #include <stdlib.h> #include <stirng.h>

char *Eliminar(char*, char*);

int main (){ char Texto[200]; char Subcadena[10];

system("clear");

printf("Introduzca el texto:\n");

fgets(text,200,stdin);

printf("Introduzca la subcadena:\n"); scanf("%[^\n]",Subcadena);

}

printf("Texto resultante return 0;

%s\n", Eliminar(Texto, Subcadena));

char *Eliminar(char *Texto, char *Subcadena){ char *P; int Ct=0;

P=Texto;

P=strstr(P,Subcadena);

if(P)

{

do

{

 

*P=*(P+strlen(Subcadena));

Ct++;

}

while (*(P+strlen(Subcadena)-1));

}

return Texto;

}

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 19

} return Texto; } MP 11 – UF 01 – Módulo 6 – Fundamentos Programación. Página

9.2.

CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

9.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. 9.3. EXPLICACIÓN DEL PROGRAMA. En este programa se implementa

9.3. EXPLICACIÓN DEL PROGRAMA.

En este programa se implementa la función Eliminar que tiene el protocolo:

char *Eliminar(char *Texto, char *Subcadena)

Esta función busca en la cadena Texto, la cadena Subcadena. Esta búsqueda se hace con la función de la librería estándar strstr(), la cual retorna un puntero a la posición donde aparece por primera vez la subcadena Subcadena en la cadena Texto. Si la subcadena no se encuentra en Texto; la función strstr() retorna un puntero NULL y se salta el bucle y acaba la función Eliminar(). Si la cadena se encuentra, el puntero P apuntará a otra posición donde comienza esta subcadena. Entonces entrará en la siguiente parte del código:

do

{

 

*P=*(P+strlen(Subcadena));

Ct++;

}

while (*(P+strlen(Subcadena)-1));

Lo que hace esta parte del código es desplazar todos los caracteres que hay después de la subcadena en Texto (incluyendo el carácter fin de cadena de Texto) a la izquierda un número de posiciones igual a la longitud de la subcadena:

número de posiciones igual a la longitud de la subcadena: Este bucle se realiza hasta que

Este bucle se realiza hasta que *(P+strlen(Subcadena)-1)sea el carácter '\0'. El hecho de restar -1 es debido a que la comparación se hace después de incrementar el puntero P.

comparación se hace después de incrementar el puntero P . MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 20

hace después de incrementar el puntero P . MP 11 – UF 01 – Módulo 6

10.

PRÁCTICA 9:

FRECUENCIA DE LAS LETRAS.

En esta práctica veremos un útil programa que permite contar el número de veces que aparece cada carácter en un texto. También veremos el uso de las funciones tolower() e isalpha().

10.1. DESARROLLO DE LA PRÁCTICA.

Crearemos un nuevo archivo de tipo C++ denominado m6p09.c con el siguiente código:

//m6p09.cc - FRECUENCIA DE LAS LETRAS -

#include <stdio.h> #include <stdlib.h> #include <ctype.h>

int main()

{

int C, Frecuencia[26]={0};

system("clear");

printf("Introduzca un texto: \n"); printf("Presionar CTRL+D para finalizar.\n\n");

while ((C = (getchar())) != EOF)

{

if(isalpha(C)) Frecuencia[tolower(C)-97]++;

}

printf("\n\n");

for(C=0;C<26;C++)

{

printf("%c=%d\t",C+97,Frecuencia[C]);

}

printf("\n");

return 0;

}

10.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA.

return 0; } 10.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 –
return 0; } 10.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 21

10.2. CAPTURA DE LA EJECUCIÓN DEL PROGRAMA. MP 11 – UF 01 – Módulo 6 –

10.3.

EXPLICACIÓN DEL PROGRAMA.

En este programa no almacenaremos el texto por teclado en la memoria del ordenador, sino que la contabilidad de las frecuencias se hará a medida que el texto se va introduciendo.

La línea de código que hace este recuento es:

if(isalpha(C)) Frecuencia[tolower(C)-97]++;

La función isalpha() comprueba si el carácter introducido es una letra, si no es así, se ignora el carácter y no lo contabiliza. En caso positivo, se incrementa en 1 el contador de la letra correspondiente.

La función tolower() nos ahorra tener que distinguir entre mayúsculas y minúsculas ya que convierte todas las letras en minúsculas. Las letras minúsculas tienen el código ASCII comprendido entre 97 y 123, por tanto, cada aparición de la letra a hace que se incremente Frecuencia[0], cada aparición de la letra b hace que se incremente Frecuencia[1] y así sucesivamente.

Por último, una vez se ha salido del bucle de lectura (con Ctrl-Z), se imprime por pantalla la frecuencia de todas las letras.

Es importante reseñar que este programa no funciona con caracteres especiales y acentos.

programa no funciona con caracteres especiales y acentos. MP 11 – UF 01 – Módulo 6

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 22

con caracteres especiales y acentos. MP 11 – UF 01 – Módulo 6 – Fundamentos Programación.

11.

PRÁCTICA AMPLIACIÓN 1:

SOPA DE LETRAS.

En esta práctica veremos un ejemplo de punteros en funciones.

11.1. DESARROLLO DE LA PRÁCTICA.

Imaginemos que tenemos una matriz bidimensional cuadrada de caracteres de n filas y n columnas, y queremos encontrar en esta segunda matriz una palabra escondida que se puede leer en una de las cuatro direcciones siguientes:

Horizontal de izquierda a derecha.

Horizontal de derecha a izquierda.

Vertical de arriba abajo.

Vertical de abajo a arriba.

Vertical de arriba abajo.  Vertical de abajo a arriba. Por ejemplo, en la siguiente matriz

Por ejemplo, en la siguiente matriz de '7 x 7' podemos encontrar las palabras sopa y lletres. La primera palabra se encuentra en la última columna vertical leyendo de abajo a arriba y la segunda palabra se encuentra en la última fila horizontal leyendo de izquierda a derecha.

esta

consideración podría formar parte de uno de los proyectos del curso.

La búsqueda de una palabra concreta se debe efectuar en 4n cadenas diferentes (si se consideran las direcciones de las diagonales, hay 8n-4 cadenas más). Estas cadenas son:

Para

simplificar

no

consideraremos

las

direcciones

de

las

diagonales,

aunque

- n líneas horizontales de izquierda a derecha;

- n líneas horizontales de derecha a izquierda;

- n líneas verticales de arriba abajo;

- n líneas verticales de abajo a arriba.

El programa que se presenta a continuación permite entrar toda la tabla de caracteres y después una palabra. El programa buscará la palabra entrada en las cuatro direcciones, en caso que se encuentre indicará en cuál de las direcciones se encuentra, además de indicar el número de fila o columna donde se encuentre.

También imprimirá toda la tabla, destacando en mayúscula los caracteres de la palabra encontrada.

Crearemos un nuevo archivo del tipo C++ denominado m5pa01.cc con el siguiente código:

I //m6pa1.c - SOPA DE LETRAS -

#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h>

void introduccion_datos(void); void hor_derecha(char *); void hor_izquierda(char *); void ver_abajo(char palabra[]); void ver_arriba(char palabra[]); void mostrar_tablero(); void inicializar_tablero();

void mostrar_tablero(); void inicializar_tablero(); char tablero[11][11]; unsigned dimension; MP 11 – UF 01

char tablero[11][11]; unsigned dimension;

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 23

char tablero[11][11]; unsigned dimension; MP 11 – UF 01 – Módulo 6 – Fundamentos Programación. Página

II

int main ()

{

char palabra[11];

introduccion_datos();

do{ printf("Introduzca la palabra a buscar\n");

printf("(Presionar 0+INTRO para acabar) scanf(" %s",palabra); printf("\n\n"); system("clear");

hor_derecha(palabra);

hor_izquierda(palabra);

ver_abajo(palabra);

ver_arriba(palabra);

mostrar_tablero();

inicializar_tablero();

}

while(*palabra!='0');

return 0;

}

");

III void hor_derecha(char palabra[])

{

unsigned i,j; char texto[10];

char *puntero;

for(i=0;i<dimension;i++)

{

 

for(j=0;j<dimension;j++) texto[j]=tablero[i][j];

if(!(puntero=strstr(texto, palabra))) continue;

for (j=0;j<strlen(palabra);j++) puntero[j]=toupper(puntero[j]);

for(j=0;j<dimension;j++) tablero[i][j]=texto[j];

printf("\n Esta en la fila horizontal derecha %d\n",i); return;

}

}

IV void hor_izquierda(char palabra[])

{

 

unsigned i,j; char texto[10]; char *puntero;

for(i=0;i<dimension;i++)

{

for(j=0;j<dimension;j++) text[dimension-j-1]=tablero[i][j];

if(!(puntero=strstr(text, palabra))) continue;

for (j=0;j<strlen(palabra);j++) puntero[j]=toupper(puntero[j]);

for(j=0;j<dimension;j++) tablero[i][j]=text[dimension-j-1];

printf("\n Esta en la fila horizontal izquierda %d\n",i); return;

}

}

fila horizontal izquierda %d\n",i); return; } } MP 11 – UF 01 – Módulo 6 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 24

izquierda %d\n",i); return; } } MP 11 – UF 01 – Módulo 6 – Fundamentos Programación.

V

void ver_abajo(char palabra[])

{

 

unsigned i,j; char texto[10]; char *puntero;

for(i=0;i<dimension;i++)

{

for(j=0;j<dimension;j++) texto[j]=tablero[j][i];

if(!(puntero=strstr(texto, palabra))) continue;

for (j=0;j<strlen(palabra);j++) puntero[j]=toupper(puntero[j]);

for(j=0;j<dimension;j++) tablero[j][i]=texto[j];

printf("\n Esta en la fila vertical hacia abajo %d\n",i); return;

}

}

VI void ver_arriba(char palabra[])

{

unsigned i,j; char texto[10]; char *puntero;

for(i=0;i<dimension;i++)

{

 

for(j=0;j<dimension;j++) texto[j]=tablero[dimension-j-1][i];

if(!(puntero=strstr(texto, palabra))) continue;

for (j=0;j<strlen(palabra);j++) puntero[j]=toupper(puntero[j]);

for(j=0;j<dimension;j++) tablero[dimension-j-1][i]=text[j];

printf("\n Esta en la fila vertical hacia arriba %d\n",i); return;

}

}

VII void introduccion_datos(void)

{

 

unsigned i;

printf("Introduzca la dimensión de la sopa de letras\n"); scanf(" %d",&dimension);

printf("Introduzca el tablero por filas\n"); for (i=0;i<dimension;i++) scanf(" %s",tablero[i]);

}

VIII void inicializar_tablero()

{

 

unsigned i,j;

for(i=0;i<dimension;i++)

{

for(j=0;j<dimension;j++)

{

tablero[i][j]=tolower(tablero[i][j]);

}

}

}

tablero[i][j]=tolower(tablero[i][j]); } } } MP 11 – UF 01 – Módulo 6 – Fundamentos

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 25

} } } MP 11 – UF 01 – Módulo 6 – Fundamentos Programación. Página 25

IX

void mostrar_tablero()

{

 

unsigned i,j;

for(i=0;i<dimension;i++)

{

for(j=0;j<dimension;j++)

{

printf("%c",tablero[i][j]);

}

printf("\n");

}

}

11.2. EXPLICACIÓN DEL PROGRAMA.

Para facilitar la explicación del código, se ha separado en 9 partes, la primera consiste en las declaraciones globales y archivos incluidos, la segunda es la función principal y las 7 restantes las diferentes funciones utilizadas.

La matriz de caracteres que formará la sopa de letras se declara como una matriz global para poder modificarla desde todas las funciones. También se declara como global la variable dimensión, que almacena el número de filas o columnas de esta matriz.

Las siete funciones de este programa son:

Introducción_datos(). Esta función permite obtener del teclado la dimensión y los caracteres de la sopa de letras.

hor_derecha(), hor_izquierda(), ver_abajo(), ver_arriba(). Estas cuatro funciones comprueban si la palabra buscada se encuentra en cada una de las n filas o columnas correspondientes, en caso afirmativo indica donde la ha encontrado. También cambia los caracteres encontrados de la palabra a mayúsculas con la función toupper(). De esta forma, cuando se muestre el tablero por pantalla, se verá destacada la palabra buscada.

mostrar_tablero. Muestra por pantalla el tablero. En el caso que se haya encotrado la palabra buscada, los caracteres de esta, dentro del tablero, se verán en mayúsculas.

Inicializar_tablero. Para no tener que buscar otra palabra en la misma sopa de letras, esta función únicamente cambia a minúsculas todas las letras. Esto se hace con la función tolower() que es la inversa de toupper().

la función tolower() que es la inversa de toupper() . MP 11 – UF 01 –

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 26

tolower() que es la inversa de toupper() . MP 11 – UF 01 – Módulo 6

12.

EJERCICIOS.

1) Anagramas.

Se dice que una palabra es anagrama de otra si contienen las mismas letras y el mismo número de veces cada una, aunque estén en orden diferente. Ejemplo de palabras que lo son:

estén en orden diferente. Ejemplo de palabras que lo son: En Internet hay buscadores y/o generadores

En Internet hay buscadores y/o generadores de anagramas. Escribiremos un programa C/C++ que contenga una función denominada int anagramas (char, char), que recogerá dos palabras, de 20 caracteres como máximo y retorne 1 si son anagramas y 0 en caso contrario. Denominaremos al programa m6e1.c dentro de la carpeta Módulo_6.

2) Insertar cadena de caracteres.

Escribiremos una función denominada void InsertarCad (char *cadena1, char *cadena2, int pos) que permita insertar una cadena (cadena2) dentro de otra cadena (cadena1) a partir de una posición determinada. Consideraciones:

Si pos es más grande que la longitud de cadena1, entonces cadena2 se añadirá al final de cadena1.

Si en cadena1 no hay ningún resultado final, cadena1 se truncará.

Ejemplos para char cadena1[50] y char cadena2[50]:

Si cadena1 vale "Crédito Fundamentos Programación": InsertarCad(cadena1, "c4 ", 9); da como resultado "Crédito c4 Fundamentos Programación".

Si cadena1 vale "Crédito C4": InsertarCad(cadena1, "Fundamentos Programación", 9); da como resultado "Crédito C4 Fundamentos Programación". Denominaremos al programa m6e2.c dentro de la carpeta Módulo_6.

3) Los Palíndromos.

Escribiremos un programa para reconocer palíndromos. Un palíndromo es una frase que se lee igual de derecha a izquierda que de izquierda a derecha. No se tienen en cuenta los espacios. Ejemplos de palíndromos: - Se van sus naves.; - Dábale arroz a la zorra el abad.

El programa debe contener una función con el protocolo: int palindromo (char *text);.

Si el texto es un palíndromo, la función retornará el valor 1, en caso contrario retornará el valor 0.

En Internet hay buscadores y/o generadores de palíndromos. Denominaremos al programa m6e3.c dentro de la carpeta Módulo_6.

al programa m6e3.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 27

m6e3.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6 – Fundamentos

4) Sustitución.

Escribiremos un programa que implemente la función Sustituir, el protocolo del cual será:

char *Sustituir (char *Texto, char *Viejo, char *Nuevo).

Esta función debe buscar en Texto todas las apariciones de la cadena Viejo y las ha de sustituir por la cadena Nuevo. Debemos tener en cuenta que ambas serán cadenas que no necesariamente tendrán el mismo tamaño. No hace falta comprobación de límites. Se supone que la cadena Texto podrá almacenar el resultado final.

Por ejemplo:

Texto="Todos los libros del escritorio son libros mios" Viejo="libros" Nuevo="lapices" Sustituir(Texto, Viejo, Nuevo)="Todos los lapices del escritorio son lapices mios"

Denominaremos al programa m6e4.c dentro de la carpeta Módulo_6.

12.1. PROBLEMAS COMPLEMENTARIOS.

5) Frecuencia de números.

En la práctica 9, se ha hecho un recuento de letras de un texto introducido por teclado. Si se ha probado el programa, nos habremos dado cuenta que los caracteres especiales: ç. Ñ, à, í,… no los cuenta. La función isalpha() no considera a estos caracteres como letras. Reemplazaremos esta función por otra que retorne un 1 en el caso que el argumento sea un carácter a-z, A-Z, ç, Ç, ñ, Ñ, á, Á, é, É, í, Í, ó, Ó, ú, Ú, è, È, ò, Ò, ï, Ï, ü, Ü. También haremos que el programa contabilice los caracteres {a, á, à, A, Á, À} juntos, etc. Denominaremos al programa m6e5.c dentro de la carpeta Módulo_6.

6) Velocidad de escritura.

Haremos u programa que calcule el número de pulsaciones por minuto que se están escribiendo por teclado.

En el programa debe solicitar la introducción de un texto. El programa detectará la primera pulsación y comenzará a contar el tiempo desde entonces. Para acabar el texto, el usuario deberá teclear CTRL-z. Entonces, el programa deberá indicarnos:

1. El número total de pulsaciones;

2. El tiempo en segundos empleado;

3. La velocidad expresada en pulsaciones por minuto.

Para poder contar el tiempo tenemos la función time() la declaración de la cual se encuentra en el archivo de cabecera time.h. Esta función retorna el tiempo en segundos.

Si la primera vez que se presiona una tecla se asigna a una variable entera, por ejemplo Tiempo, el valor de time(NULL): Tiempo=time(NULL);

Cuando se abae de introducir el texto, el tiempo empleado es igual a : time(NUL)-Tiempo

Denominaremos al programa m6e6.c dentro de la carpeta Módulo_6.

al programa m6e6.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 28

m6e6.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6 – Fundamentos

7) Palabra más utilizada.

Escribiremos un programa que dado un texto introducido por teclado, nos diga cuál es la palabra más utilizada y el número de veces que se repite. Se considerará que:

1. Haya al menos una palabra;

2. El espacio en blanco es el carácter separador de palabras;

3. Puede haber más de un espacio en blanco entre palabras;

4. Los caracteres "//" indicarán el final del texto.

Denominaremos al programa m6e7.c dentro de la carpeta Módulo_6.

8) Código Morse.

El código Morse fue desarrollado por Samuel Morse en 1832 para el sistema telegráfico. Este código asigna a cada letra del abecedario y a los dígitos (del 0 al 9) una serie de puntos y rallas. En los sistemas audibles, el punto representa un sonido corto y la ralla un sonido largo. El espacio se indica mediante un periodo corto en el que no se transmite ningún sonido.

Consideraciones a tener en cuenta en nuestro programa:

1. Un espacio en blanco separará caracteres;

2. Tres espacios en blanco consecutivos separarán palabras;

3. El carácter "/" indicará el final del texto.

Escribiremos un programa que contenga una función para codificar en Morse un texto leído por teclado y otro para pasar de Morse a los correspondientes caracteres alfabéticos.

Estas son las letras del abecedario y su correspondiente código Morse:

letras del abecedario y su correspondiente código Morse: Denominaremos al programa m6e8.c dentro de la carpeta

Denominaremos al programa m6e8.c dentro de la carpeta Módulo_6.

al programa m6e8.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 29

m6e8.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6 – Fundamentos

9) Palabra más utilizada.

En la práctica 1 se ha implementado una función que permite invertir una palabra. El hecho de utilizar la función scanf() nos impide utilizarla para invertir frases enteras (cadenas con espacios). Realizaremos las modificaciones necesarias para permitir esta eventualidad. Denominaremos al programa m6e9.c dentro de la carpeta Módulo_6.

10) Coste de un telegrama.

El coste de un telegrama es una cantidad fija multiplicada por el número de palabras que contiene, teniendo en consideración lo siguiente:

1. Si la palabra contiene más de 10 letras y menos de 20 cuenta como dos palabras;

2. Si la palabra tiene 20 letras o más, y menos de 30 la contaremos como 3 palabras;

3. Si la palabra tiene 30 letras o más, la contaremos como 4 palabras;

4. Puede haber más de un espacio en blanco entre ellas;

5. El telegrama acaba con el carácter punto ".".

Escribiremos un programa que solicite un telegrama (entrada de texto) y calcule su coste a razón de 0,10€ por palabra.

Denominaremos al programa m6e10.c dentro de la carpeta Módulo_6.

al programa m6e10.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6

MP 11 UF 01 Módulo 6 Fundamentos Programación.

Página 30

m6e10.c dentro de la carpeta Módulo_6. MP 11 – UF 01 – Módulo 6 – Fundamentos