Zwei Textdateien miteinander vergleichen
-
Alles klar, danke.
-
Es wäre noch sinnvoll die Größe der Datei zu vergleichen, bevor man diese Byteweise untersucht. Dadurch lässt sich definitiv Zeit sparen.
-
#include <fstream> #include <string> #include <iostream> bool equal(const std::string& filename1, const std::string filename2) { std::ifstream f1(filename1.c_str()); std::ifstream f2(filename2.c_str()); f1.seekg(0, std::ios_base::end); f2.seekg(0, std::ios_base::end); if(f1.tellg() != f2.tellg()) { return false; } f1.seekg(0); f2.seekg(0); char c1, c2; while(f1.get(c1) && f2.get(c2)) { if(c1 != c2) { return false; } } return true; } int main() { if(equal("datei1.txt", "datei2.txt")) { std::cout << "Die Dateien sind gleich." << std::endl; } else { std::cout << "Die Dateien sind unterschiedlich." << std::endl; } }
-
Wenn du davon ausgehst, dass die Dateien gleich sind und nicht allzu groß, würde ich an deiner Stelle beide Dateien in einen std::string einlesen und vergleichen. Gepuffertes Einlesen ist nämlich AFAIK (deutlich) schneller.
bool are_files_equal(const char *filename1, const char *filename2) { std::ifstream i1(filename1), i2(filename2); //hier evtl. vorher noch Größenvergleich if(!i1.is_open() || !i2.is_open()) { throw std::runtime_error("files could not be opened"); } std::ostringstream s1, s2; s1 << i1.rdbuf(); s2 << i2.rdbuf(); return s1.get() == s2.get(); }
-
Ich will in die gleiche Lücke schlagen wie wxskip, bin nur etwas langsamer beim Schreiben des Beitrags, weil ich auch für den Fall großer Dateien eine funktionierende Funktion wollte:
#include<cstddef> #include<fstream> #include<string> bool fequal(const std::string& filename1, const std::string filename2) { std::ifstream f1(filename1.c_str(), std::ios_base::in | std::ios_base::binary); std::ifstream f2(filename2.c_str(), std::ios_base::in | std::ios_base::binary); // Länge herausfinden f1.seekg(0, std::ios_base::end); f2.seekg(0, std::ios_base::end); std::streamsize length1 = f1.tellg(); std::streamsize length2 = f2.tellg(); // Unterschiedliche Länge -> Dateien verschieden. if (length1!=length2) return false; // Wieder zurück auf Anfang f1.seekg(0); f2.seekg(0); // In Blöcken lesen und vergleichen const std::streamsize blocksize=4096; // Willkürliche Abwägung zwischen Geschwindigkeit und Speicherbedarf for (std::streamsize counter=length1; counter > 0; counter-=blocksize) { char block1[blocksize], block2[blocksize]; f1.read(block1, blocksize); f2.read(block2, blocksize); // Ganze ints vergleichen um die bevorzugte Wortgröße des Prozessors auszunutzen std::streamsize ints_read=f2.gcount()/sizeof(int); for(int i=0; i<ints_read; ++i) if (reinterpret_cast<int *>(block1)[i] != reinterpret_cast<int *>(block2)[i]) return false; } // Alle Tests erfolgreich, Dateien gleich return true; }
Jedenfalls habe ich ja neulich gelernt, dass read wesentlich schneller ist als get und ich bin nicht lernresistent.
P.S.: Ob der Trick mit den ints geschwindigkeitsmäßig etwas bringt weiß ich jetzt nicht, weil ich es nicht ausgiebig getestet habe. Sehr gut möglich, dass dies ohnehin optimiert werden würde.
P.P.S.: Ach, ich Blindfisch! Dafür könnte man natürlich auch gleich memcmp nehmen. Das wäre wesentlich besser!
-
Hier noch eine kleine Änderung Deines Codes
.... .... // Unterschiedliche Länge -> Dateien verschieden. if (length1!=length2) return false; return ::std::equal(::std::istream_iterator<char>(f1), ::std::istream_iterator<char>(), ::std::istream_iterator<char>(f2)); }
Schööön kurz
Lichtlein
-
Da ist aber der gesamte Sinn meines Codes futsch, dass ich eben nicht zeichenweise auslesen möchte.
-
Danke Leute, funktioniert natürlich.
Wäre es aufwendig wenn man es mit Oberfläche sowie freier Pfad-/Dateiauswahl programmiert?MfG
-
Kein_Geek schrieb:
Wäre es aufwendig wenn man es mit Oberfläche sowie freier Pfad-/Dateiauswahl programmiert?
Meinst du mit GUI? Kommt auf deine Kenntnisse in diesem Bereich an. Du müsstest dich auch für ein GUI-Framework entscheiden.
::std
Wer schreibt denn sowas?
-
SeppJ schrieb:
P.P.S.: Ach, ich Blindfisch! Dafür könnte man natürlich auch gleich memcmp nehmen. Das wäre wesentlich besser!
Und man könnte gleich memory mapped Files verwenden - das wäre dann noch schneller