domingo, 4 de mayo de 2014

Comparando dos archivos de texto en C++.

Buenas gente. Hoy os traigo un pequeño proyecto muy bien comentado de un amigo donde yo he aprendido mucho y espero que vosotros también. Solo lo he probado con la extensión .txt, pero supongo que funcionaría con cualquiera. He de decir que en linux esto es innecesario puesto que se puede hacer con un simple diff, pero aquí estamos para aprender, ¿no? :p

NOTA: Debido al define limpiar, este código funciona con Windows y Linux, pero no con otros Sistemas Operativos como iOS. Sería cuestión de añadirle uno para tu sistema ;)

#include <iostream> // entrada y salida por consola
#include <fstream>  // entrada y salida por ficheros
#include <string>   // para string
#include <stdlib.h> // para system
#include <stdio.h>  //para remove
#include <iomanip>  // pata setw
using namespace std;

#ifdef _WIN32
#define  limpiar  system("cls")
#endif

#ifdef linux
#defain  limpiar   system("clear");
#endif

int main() {
 cout << "No te equivoques a la hora de escribir, la ruta, o el archivo, porque si no deberas volver a empezar...\n\n";
 cout << "\tIntroduce la ruta del primer archivo: ";
 string s1;
 getline(cin, s1);//cojo de la consola la primera ruta con espacios incluidos

 cout << "\tIntroduce la ruta del segundo archivo: ";
 string s2;
 getline(cin, s2); // y aqui la segunda ruta

 const char* Ruta1 = s1.c_str(); //Las transformo a const char ya que mas a delante
 const char* Ruta2 = s2.c_str(); //las utilizare para abrir ficheros, y si no son const char se queja el compilador
 //basicamente lo que hace s1.c_str() es asignar al puntero Ruta1 la posicion donde empieza el string, 

 ifstream File1(Ruta1, ios::in); //Abrimos los dos ficheros en modo de lectura
 ifstream File2(Ruta2, ios::in); //

 if (File1.fail() || File2.fail()){ // en el caso de que uno de los dos ficheros no exista...
  limpiar;
  cout << "Ha habido un error, escriba correctamente la Ruta o el archivo\n";
  cout << "Aprete intro para continuar";
  cin.get();  // esperamos a que aprete intro
  limpiar;
  main();     //volvemos a empezar
 }
 else {//si ambos ficheros se han encontrado y se han abierto correctamente...
  ofstream comparacion("Comparacion.txt", ios::out); //declaramos y abrimos otro fichero en modo de escritura
  bool iguales = true;
  int cont = 0, linea = 0;
  limpiar;
  cout << "Iniciando comparacion....\n";

  while (!File1.eof() && !File2.eof()) { // mientras que ninguno de los dos ficheros se haya acabado
   ++linea;
   string a, b;
   getline(File1, a); // metemos en el string a la primera linea del fichero 1
   getline(File2, b); // metemos en el string b la primera linea del fichero 2
   if (a != b) { // si son diferentes....
    ++cont;
    cout << flush << "Error numero " << cont << " en la linea " << linea << endl << flush;
    comparacion << flush << "Error numero " << cont << " en la linea " << linea << endl << flush;
    iguales = false;
    cout << setw(20) << right << s1 << " : " << a << endl;
    cout << setw(20) << right << s2 << " : " << b << endl;
    comparacion << setw(20) << right << s1 << " : " << a << endl;
    comparacion << setw(20) << right << s2 << " : " << b << endl;
   }//Sacamos por pantalla en un formato determinado las diferencias y tambien en un fichero
  }
  if (!File1.eof() && File2.eof()) {//en el caso de que hayamos llegado al final del primer fichero pero no del segundo...
   cout << "El archivo " << Ruta2 << " es mas corto que " << Ruta1 << endl;
   comparacion << "El archivo " << Ruta2 << " es mas corto que " << Ruta1 << endl;
  }
  if (!File2.eof() && File1.eof()) {//... al reves que el anterior
   cout << "El archivo " << Ruta1 << " es mas corto que " << Ruta2 << endl;
   comparacion << "El archivo " << Ruta1 << " es mas corto que " << Ruta2 << endl;
  }
  comparacion.close();//cerramos el fichero de salida!! (esto es importante cuando abrimos un fichero mas a delante se ha de cerrar)
  if (iguales) cout << "\nEnhorabuena los dos ficheros son iguales\n";
  cout << "*--------Fin de la comparacion-------*\n";
  cout << "Pulse s si quiere guardar los datos en un archivo\n En caso contrario pulse otra letra\n";
  char c;
  cin >> c;
  if (c != 's') remove("Comparacion.txt");//en el caso de que el usuario no quiera un fichero con las diferencias sacadas por la
  //consola, pues el que habiamos creado y llenado con todos los datos lo eliminamos
 }
} 

Bueno, espero que hayáis aprendido tanto como yo con esta práctica :p La verdad es que la veo muy interesante.

Saludos ;)

No hay comentarios:

Publicar un comentario