Benutzer:Stefan Knauf/Dateiumfassenderdurchsuchungsprogramm.cpp


C++-Programm, das eine Datei nach allen im Suchschluessel-Vector angegebenen Suchstrings durchsucht und die Funde am Bildschirm ausgibt. Das Programm durchsucht die Datei einfach linear nach jedem der Suchwörter. Der Vorteil gegenüber dem Dateidurchsuchungsprogramm.cpp, das pro Ausführung eine Datei nur nach einem Suchwort durchsuchen kann, besteht nur darin, dass bei diesem Programm die zu durchsuchende Datei nur einmal von der Festplatte gelesen werden muss – wenn für jedes Suchwort einmal das Dateidurchsuchungsprogramm.cpp ausgeführt würde, müsste die zu durchsuchende Datei für jedes Suchwort erneut von der Festplatte geladen werde, was entsprechend länger dauert.



//C++

// 30.6.2013


using namespace std;

#include<iostream> //enthält die Befehle zum Schreiben auf den Bildschirm
#include<fstream> //enthält die Befehle zum Schreiben in und zum Lesen aus Dateien
#include<string> //enthält den Kram zu Strings, also zu Zeichenketten
#include<vector> //für die praktische Vektor-Klasse vector<irgendein Typ>
#include<time.h>  //enthält time(NULL)


void schreibeintVector (vector<int> x) //wurde nur zum Testen benötigt
 {for (int i=0; i<x.size(); i++)
   {cout << "Stelle " << i << ": " << x[i] << endl;
   }
 }

string schreibeZiffer(const long long int & z) //wandelt eine ganze Zahl von 0 bis 9 in einen String, der genau diese Zahl enthält
 {string Ziffer;
  switch (z)
   {case 1 : Ziffer = "1"; break;
    case 2 : Ziffer = "2"; break;
    case 3 : Ziffer = "3"; break;
    case 4 : Ziffer = "4"; break;
    case 5 : Ziffer = "5"; break;
    case 6 : Ziffer = "6"; break;
    case 7 : Ziffer = "7"; break;
    case 8 : Ziffer = "8"; break;
    case 9 : Ziffer = "9"; break;
    case 0 : Ziffer = "0"; break;
    default : cerr << "Der Ziffernmacher stößt auf was Unziffriges!" << endl;
   }
  return Ziffer;
 }

string schreibeZahlmitPunkten (long long int z) //wandelt eine ganze Zahl in einen String mit Tausenderpunkten
 {string Zahl=""; //für die Ausgabe
  if (z==0)
   {Zahl="0";
   }
  else
   {if (z<0)
     {Zahl="-"+schreibeZahlmitPunkten(-1*z);
     }
    else
     {int j=0;
      while (z>0)
       {if (j==3)
         {Zahl = "."+Zahl;
          j=0;
         }
        Zahl = schreibeZiffer(z%10)+Zahl;
        z/=10;
        j++;
       }
     }
   }
  return Zahl;
 }


bool Suchschluesselpruefer (const vector<string> & Suchschluessel) //gibt true zurück, wenn der "Vektor" mit den Suchschlüsseln nicht leer ist und kein Suchschlüssel leer ist, sonst false
 {bool Rueckgabe=true;
  if (Suchschluessel.size()>0)
   {for (int i=0; i<Suchschluessel.size(); i++)
     {if (Suchschluessel[i].size()==0)
       {return false;
       }
     }
   }
  else
   {Rueckgabe=false;
   }
  return Rueckgabe;
 }

vector< vector<string::size_type> > durchsucheZeileumfassender (const string & Zeile, const vector<string> & Suchschluessel)
//durchsucht den im ersten Argument gegebenen String nach allen im "Vektor" angegebenen Strings;
//benötigt, dass es mindestens einen zu suchenden String gibt und alle zu suchenden Strings nicht leer sind;
//gibt einen "Vektor" zurück, der in Eintrag i einen "Vektor" mit den Stellen enthält, an denen Suchschluessel i gefunden wurde;
 {vector< vector<string::size_type> > Trefferlisten(Suchschluessel.size());
  for (int i=0; i<Trefferlisten.size(); i++)
   {Trefferlisten[i].resize(0);
   }
  for (string::size_type i=0; i<Suchschluessel.size(); i++)
   {string::size_type n=0;
    while (n<Zeile.size())
     {n=Zeile.find(Suchschluessel[i], n);
      if (n!=string::npos)
       {Trefferlisten[i].push_back(n);
        n++;
       }
     }
   }
  return Trefferlisten;
 }

void Dateienumfassenderdurchsuchungsprozedur (const string & Dateiname, const vector<string> & Suchschluessel) //durchsucht eine Datei nach den Suchschlüsseln und gibt die Treffer am Bildschirm aus
 {if (Suchschluesselpruefer(Suchschluessel)==true)
   {long long int Zeilennummer=1; //um die Zeilennummer nachzuhalten
    vector<bool> gefunden(Suchschluessel.size()); //für den Anfang alle false
    vector<long long int> Trefferzahl(Suchschluessel.size()); //für den Anfang alle =0
    for (int i=0; i<Suchschluessel.size(); i++)
     {gefunden[i]=false;
      Trefferzahl[i]=0;
     }
    ifstream Datei;
    Datei.open(Dateiname.c_str());
    if (!Datei.good())
     {cerr << "Beim Öffnen der Datei " << Dateiname << " ist ein Fehler aufgetreten!" << endl;
     }
    while (Datei.good())
     {string Zeile;
      getline(Datei, Zeile); //schreibt eine Zeile der Datei in die Variable Zeile
      vector< vector<string::size_type> > Zeilentrefferliste = durchsucheZeileumfassender(Zeile, Suchschluessel);
      for (int Suchschluesselnummer=0; Suchschluesselnummer<Suchschluessel.size(); Suchschluesselnummer++)
       {if (Zeilentrefferliste[Suchschluesselnummer].size()>0) //die Bedingung ist erfüllt, wenn der Suchschlüssel in der Zeile vorkam
         {gefunden[Suchschluesselnummer]=true;
          Trefferzahl[Suchschluesselnummer]+=Zeilentrefferliste[Suchschluesselnummer].size();
          if (Zeilentrefferliste[Suchschluesselnummer].size()>1) //die Bedingung ist erfüllt, wenn es mehr als einen Treffer in der Zeile gibt
           {cout << "In Zeile " << schreibeZahlmitPunkten(Zeilennummer) << " wurde das Suchwort \"" << Suchschluessel[Suchschluesselnummer] << "\" gefunden, und zwar an folgenden Positionen:\n";
            for (int i=0; i<Zeilentrefferliste[Suchschluesselnummer].size(); i++)
             {cout << schreibeZahlmitPunkten(Zeilentrefferliste[Suchschluesselnummer][i]+1) << '\n';
             }
           }
          else // hier gibt es genau einen Treffer in der Zeile
           {cout << "In Zeile " << schreibeZahlmitPunkten(Zeilennummer) << " wurde das Suchwort \"" << Suchschluessel[Suchschluesselnummer] << "\" nur an folgender Position gefunden:\n";
            cout << schreibeZahlmitPunkten(Zeilentrefferliste[Suchschluesselnummer][0]+1) << '\n';
           }
          cout << endl;
         }
       }
      Zeilennummer++;
     }
    Datei.close();
    for (int Suchschluesselnummer=0; Suchschluesselnummer<Suchschluessel.size(); Suchschluesselnummer++)    
     {if (gefunden[Suchschluesselnummer]==false)
       {cout << "Das Suchwort \"" << Suchschluessel[Suchschluesselnummer] << "\" wurde in der Datei " << Dateiname << " nicht gefunden.\n";
       }
      else
       {if (Trefferzahl[Suchschluesselnummer]>1)
         {cout << "Das Suchwort \"" << Suchschluessel[Suchschluesselnummer] << "\" wurde in der Datei " << Dateiname << " an " << schreibeZahlmitPunkten(Trefferzahl[Suchschluesselnummer]) << " Stellen gefunden.\n";
         }
        else //hier gab es in der Datei genau einen Suchtreffer
         {cout << "Das Suchwort \"" << Suchschluessel[Suchschluesselnummer] << "\" wurde in der Datei " << Dateiname << " an genau einer Stelle gefunden.\n";
         }
       }
     }
    cout << endl;
    cout << "Falls ein Suchwort ein echtes Anfangsstück als Endstück hat, können sich die Treffer überschneiden, z.B. würde das Suchwort \"dd\" im Text \"ddd\" zweimal gefunden." << endl;
   } 
  else
   {cout << "Es gibt kein Suchwort oder ein Suchwort ist leer!" << endl;
   } 
 }
 
int main()
 {time_t Startzeit = time(NULL);
  vector<string> Suchschluessel(0);
  Suchschluessel.push_back("Jutta"); //Ab hier stehen die Suchwörter, hier "Jutta", "Michael" und "Matthias".
  Suchschluessel.push_back("Michael");
  Suchschluessel.push_back("Matthias");
  Dateienumfassenderdurchsuchungsprozedur("dewiki-latest-pages-articles.xml", Suchschluessel); //Das erste Argument ist der Name der zu durchsuchenden Datei.
  cout << time(NULL) - Startzeit << '\n'; //gibt die benötigte Zeit in Sekunden aus
  cout << '\a' << endl; //gibt einen Ton aus, um das Ende des Programms zu signalisieren
  return 0;
 }