/*************** Practica 01. Traductor de codigo PseudoHTML ******************
*
* Nombre de Fichero: pr01##.cpp
*
* Proposito: este programa sirve para traducir un archivo escrito en codigo
* pseudohtml a codigo html estandar y guardar el resultado en
* en un fichero distinto.
*
* Condiciones de Final Anormal y Mensajes de Error y Advertencia
*
* --> No hay final anormal
* --> No hay mensajes de error
*
* Historia de Desarrollo:
* Fecha Autor Id Cambio Version Descripcion del cambio
* -------- -------------- --------- ------- ----------------------
* 25-03-04 0 1.0
*
*****************************************************************************/
#include <iostream.h>
#include <stdlib.h>
#include <string>
#include <fstream>
const int TAM=100;
struct etiquetas
{
string html, pseudohtml;
};
typedef etiquetas vector[TAM];
void LeerTabla(ifstream &tabla,vector v,int &i);
void OrdenarTabla(vector &v, int i);
string LeerEtiqueta(ifstream &f);
string TraducirEtiqueta(string &etiqueta,vector v,int i);
void Traducir(ofstream &g,ifstream &f,vector v,int i);
void Salir(bool &fallo);
int main()
{
string tabla_path, f_path, g_path; //aqui se guardaran las rutas de los ficheros
ifstream tabla;
ifstream f;
ofstream g;
vector v;
int i;
bool fallo;
do
{
i=-1;
fallo=false;
system("cls");
cout << "--- TRADUCTOR DE CODIGO PSEUDOHTML---\n\n\n";
cout << "\nIntroduce la ruta del fichero con las equivalencias: ";
cin >> tabla_path;
tabla.open(tabla_path.c_str());
if(!tabla)
{
system("cls");
cout << "Error abriendo " << tabla_path << "\n\n";
fallo=true;
}
else
{
LeerTabla(tabla,v,i);
OrdenarTabla(v,i);
cout << "\nIntroduce la ruta del fichero a traducir: ";
cin >> f_path;
f.open(f_path.c_str());
if(!f)
{
system("cls");
cout << "Error abriendo " << f_path << "\n\n";
fallo=true;
tabla.close();
}
else
{
cout << "\nIntroduce la ruta del fichero traducido que se va a crear: ";
cin >> g_path;
g.open(g_path.c_str());
if(!g)
{
system("cls");
cout << "Error creando" << g_path << "\n\n";
fallo=true;
f.close();
}
else
{
Traducir(g,f,v,i);
g.close();
f.close();
tabla.close();
}
}
}
if(fallo==false)
{
cout << "\n\nEl fichero ha sido traducido\n\n\n";
Salir(fallo);
}
else
Salir(fallo);
}while(fallo==true);
return 0;
}
/*------------------------------------*
*
* La funcion LeerTabla introduce
* dentro de un vector de estructuras
* el contenido del fichero tabla
*
*-------------------------------------*/
void LeerTabla(ifstream &tabla, vector v, int &i)
{
string aux;
while(tabla >> aux)
{
i++;
v[i].html=aux;
tabla >> aux;
v[i].pseudohtml=aux;
}
}
/*--------------------------------------*
*
* La funcion LeerEtiqueta construye una
* cadena de caracteres a partir de los
* caracteres que va leyendo del fichero
* f hasta encontrar un espacio o un menor
* que, y al final devuelve esa cadena de
* caracteres construida
*
*---------------------------------------*/
string LeerEtiqueta(ifstream &f)
{
char c;
string etiqueta;
etiqueta = "<";
c = f.get ();
while (!f.eof () && c != ' ' && c != '>')
{
etiqueta += c;
c = f.get ();
}
if (!f.eof () )
etiqueta += c;
return etiqueta;
}
/*--------------------------------------------------
*
* A la funcion TraducirEtiqueta se le proporciona
* una etiqueta. A continuacion busca esa misma
* etiqueta dentro del vector de estructuras que
* contiene la tabla de equivalencias. Cuando la
* encuentra devuelve la etiqueta equivalente en
* codigo HTML
*
*--------------------------------------------------*/
string TraducirEtiqueta(string &etiqueta,vector v,int i)
{
int j=0;
bool enc=false;
/*
el bucle se repite:
mientras no llegue al final de la longitud del vector Y mientras
no se haya encontrado la etiqueta Y mientras la etiqueta que
tenemos sea "alfabeticamente mayor" que las que comprobamos
en el vector de estructuras
*/
while((j <= i) && (enc==false) && (etiqueta >= v[j].pseudohtml))
{
if(v[j].pseudohtml==etiqueta)
{
etiqueta = v[j].html;
enc=true;
}
j++;
}
return etiqueta;
}
/*---------------------------------------*
*
* La funcion Traducir va escribiendo los
* resultados de la traduccion en un nuevo
* fichero g
*
*----------------------------------------*/
void Traducir(ofstream &g,ifstream &f,vector v,int i)
{
char aux;
string etiqueta;
while(!f.eof())
{
aux = f.get();
/*
cuando se encuentre un menor llamamos
a las funciones que leen la etiqueta
y la traducen
*/
if(aux == '<')
{
etiqueta = LeerEtiqueta(f);
etiqueta = TraducirEtiqueta(etiqueta,v,i);
g << etiqueta; // escribimos en el fichero la etiqueta traducida
}
/*
si no se ha encontrado un menor significa que no es ninguna etiqueta
que debamos traducir, por lo tanto escribiremos en el fichero el
caracter que hayamos leido
*/
else
/*
si la ultima etiqueta es </html> significa que se ha llegado
al final del codigo html y no hay que escribir nada mas, de lo
contrario nos escribiria un caracter raro
*/
if(etiqueta != "</html>")
g << aux;
}
}
/*----------------------------------------------------*
*
* Ordenamos alfabeticamente el vector de estructuras
* para que la busqueda en él sea más eficiente
*
*----------------------------------------------------*/
void OrdenarTabla(vector &v, int i)
{
string aux;
int a=0;
int b=1;
int pos;
while(a<i)
{
aux=v[a].pseudohtml;
while(b<=i)
{
if(aux>v[b].pseudohtml)
{
pos=b;
aux=v[pos].pseudohtml;
}
b++;
}
v[pos].pseudohtml=v[a].pseudohtml;
v[a].pseudohtml=aux;
aux=v[pos].html;
v[pos].html=v[a].html;
v[a].html=aux;
a++;
b=a+1;
}
}
/*------------------------------------------------
*
* Esta funcion modifica el valor de la variable
* fallo para salir del programa en funcion de
* la respuesta del usuario
*
*-----------------------------------------------*/
void Salir(bool &fallo)
{
string cadena;
do{
cout << "Desea salir del programa? [Si/No]\n> ";
cin >> cadena;
if((cadena=="Si")||(cadena=="si")||(cadena=="SI")||(cadena=="sI"))
fallo=false;
else
if((cadena=="No")||(cadena=="no")||(cadena=="NO")||(cadena=="nO"))
fallo=true;
else
cout << "\nLa respuesta tiene que ser \"Si\" o \"No\"\n" << endl;
}while((cadena!="Si")&&(cadena!="si")&&(cadena!="SI")&&(cadena!="sI")&&(cadena!="No")&&(cadena!="no")&&(cadena!="NO")&&(cadena!="nO"));
}