C / C++ if(dateiA == dateib)!

danthefri

Grünschnabel
hallo zusammen

ich habe ein problem ich möchte zwei dateien vergleichen.

z.b: a.txt und b.txt

bin mir aber noch nicht ganz sicher wie ich das am besten machen soll, ob grösse oder inhalt!

hat jemand schon mal so was gemacht, und noch en tipp auf lager?!

die idee:

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

using namespace std;


int send(){
cout << "daten sind nicht gleich" <<endl;
}

int stop(){
cout << "daten sind gleich" <<endl;
}

int main(int argc, char *argv[])
{
string atxt, btxt;

atxt = "inhalt der datei a.txt";
btxt = "inhalt der datei b.txt";

if (atxt == btxt){
send();
}
else{
stop();
}

system("PAUSE");
return 0;
}

danke für die hilfe, danthefri
 
also erstmal musst du natürlich in die text-buffer einlesen.
und mit der funktion strcmp kannst du strings vergleichen.
wenn du nur grösse vergleichen willst und
FILE* dat= fopen(...) zum öffnen der dateien benutzt kannst du
int size = _filelength(_fileno(dat));
benutzen um die dateilänge herauszufinden.
wenn du CreateFile benutzt, geht es mit GetFileSize
 
Also wichtig ist was möchtest du für einen Vergleich?
- binär?
- textuell?
- mit diff?
- usw...
Wenn du dir darüber im klaren bist, dann gibt es mehrere Möglichkeiten.
Der einfachste Vergleich ist:
Du möchstest 2 Dateien X-beliebigen Inhalts vergleichen, dabei ist dir Egal, ob Text oder Binärdaten drinstehen. Und das Erebnis des Vergleichs soll einfach nur gleich oder ungleich sein.
Dann gehst du folgendermaßen vor:
1. Nach der Größe vergleichen, denn wenn die ungleich ist, dann MÜSSEN die Dateien auch ungleich sein, also if(AnzahlBytesVonA != AnzahlBytesVonB).
Achtung nimm einen Datentyp der groß genug ist (int mit 4 Bytes reicht nur für Dateien die <= 4GB sind)
2. Nur wenn die Größe gleich ist, dann Byte für Byte vergleichen und wenn einmal 2 Bytes ungleich sind, dann abbrechen, denn dann sind die beiden Dateien ungleich.
Dabei gibt es natürlich auch verschiedene Vefahren, in dem man byteweise ließt oder in Blöcken. Das ist wieder abhängig von dem Einsatz des Programms.
Denn je größer die Blöcke, desto weniger Belastung fürs Filesystem bzw. Netzwerk, aber desto mehr Speicher wird benötigt, obligatorisch sind hier 64k.
So ich hoffe das hat etwas weiter geholfen.


Gruß Homer
 
und mit der funktion strcmp kannst du strings vergleichen.

Code:
 string atxt, btxt;

atxt = "inhalt der datei a.txt";
btxt = "inhalt der datei b.txt";

if (atxt == btxt){

In deinem Fall is der Vergleich auch so vollkommen richtig, da der Operator == des
STL Strings schon genau für den Zweck des inhaltlichen Vergleiches überladen
ist, und du mit deinem obigen Code ohne Probleme auf den Stringinhalt vergleichen
kannst. Vorraussetzung is natürlich das du voher den Dateicontent in den String
geschrieben hast.

Gruß

RedWing
 
Original geschrieben von RedWing
In deinem Fall is der Vergleich auch so vollkommen richtig, da der Operator == des STL Strings schon genau für den Zweck des inhaltlichen Vergleiches überladenist, und du mit deinem obigen Code ohne Probleme auf den Stringinhalt vergleichen kannst. Vorraussetzung is natürlich das du voher den Dateicontent in den String
geschrieben hast.

stimmt, hab ich ganz vergessen.
aber ich arbeite auch nie mit string-klassen.
ich glaube, es gestaltet sich ziemlich kompliziert, in std::string daten aus einer datei einzulesen. auf jeden fall komplizierter als mit char pointern.
 
ich glaube, es gestaltet sich ziemlich kompliziert, in std::string daten aus einer datei einzulesen. auf jeden fall komplizierter als mit char pointern.
Das sehe ich nicht so:

Code:
      1 #include <iostream>
      2 #include <fstream>
      3 
      4 using namespace std;
      5 int main(){
      6 
      7         ifstream file("test.txt");
      8         string content = "";
      9         while(!file.eof()){
     10                 string temp;
     11                 file >> temp;
     12                 content += temp;
     13         }
     14         file.close();
     15 }

Ausserdem sollte man wenn man schon die Möglichkeit hat die STL zu benutzen auch
diese jene hernehmen, um falschen Speicherzugriff zu vermeiden etc.. Daher find ich
es auch unnötig wenn mans nicht unbedingt brauch auf uralte c Funktionen
zurückzugreifen, mit denen man vielleicht noch unabsichtliche Buffer Overflows
produziert.

In diesem Sinne

Gruß

RedWIng
 
Ich habe noch eine knappere Version, um eine Datei in einen String einzulesen. Dazu verwendet man istream-Iteratoren.

Code:
  std::ifstream file( "Test.txt" );
  std::string text;
  text.assign( std::istream_iterator<char>(file), std::istream_iterator<char>() );

Eigentlich hat std::string auch einen Konstruktor, den man mit den beiden Iteratoren füttern kann, was die zusätzliche assign-Zeile sparen würde, aber aus irgendeinem Grund frisst VS2003 das nicht und meldet einen Linkerfehler. Vielleicht hat jemand einen Tipp dazu? Folgendes soltle eigentlich gehen:
Code:
  std::ifstream file( "Test.txt" );
  std::string text( std::istream_iterator<char>(file), std::istream_iterator<char>() );


Übrigens scheint meine Version die CRs zu verschlucken. Kann allerdings auch sein, dass es an der AUsgabe liegt. Habe aber noch keine Zeit gefunden, daran rumzubasteln.
 
Erstmal Respekt, das nenne ich effiziente Nutzung der STL.

Zu deinem Code:

Seltsamerweise wird dein Konstruktoraufruf:
std::string text( std::istream_iterator<char>(file), std::istream_iterator<char>() );
als Funktionprototyp vom Compiler interpretiert.
Der gcc spuckt mir bei folgender Definition den gleichen Fehler aus:

Code:
      6 int main(){
      7 
      8         int add(int);
      9         cout << add;
     10         return 1;
     11 }
bzw:
Code:
      6 int main(){
      7 
      8         string text();
      9         cout << text;
     10         return 1;  }

Und dein Konstruktor Aufruf wird als funktion text interpretiert mit nem string als Rückgabewert und zwei iteratoren als Übergabeparameter.
Wenn du text dynamisch mit new allokierst und dann via dereferzieren darufzugreifst
funktioniert es ohne Probleme.
Aber vielleicht kennt sich da jemand besser aus, und kann ne genauere Erklärung
geben, bzw mir erklären wie man nen string Objekt ausser dynamisch zu erzeugen
auch anders erzuegen kann, ohne das der Compiler es als Funktionprototypen
interpretiert.

Gruß

RedWing[
 
Original geschrieben von RedWing
Daher find ich es auch unnötig wenn mans nicht unbedingt brauch auf uralte c Funktionen zurückzugreifen, mit denen man vielleicht noch unabsichtliche Buffer Overflows produziert.
Du kannst nicht zwangläufig davon ausgehen, dass die STL sicherer ist, als diese C-Funktionen. So könnten die stream-Klassen beispielsweise Implementations-abhängig die C-Funktionen verwenden, um ihre Eingabe/Ausgabe umzusetzen.
Bei mir (VSC++ 6.0) wird die Lowio-Ebene verwendet, in einer sehr ähnlichen Weise, wie auch die Stdio-Ebene sie verwendet, dabei schneiden aber die Stream-Klassen langsamer ab. (am schnellsten ist bei mir natürlich, direkt die WinApi zu benutzen, was ich auch normalerweise mache)
Ausserdem sind die Funktionen wie fread durchaus mit genug Sicherheitsüberprüfungen ausgestattet um einen Buffer-Overflow verhindern zu können.


Original geschrieben von Kachelator
Übrigens scheint meine Version die CRs zu verschlucken. Kann allerdings auch sein, dass es an der AUsgabe liegt. Habe aber noch keine Zeit gefunden, daran rumzubasteln.
Jo, ifstream öffnet standardmäßig im Text-Translated-Modus. D.h. CarryReturn-LineFeed-Paare werden durch ein einzelnes LineFeed ersetzt.
 
Ausserdem sind die Funktionen wie fread durchaus mit genug Sicherheitsüberprüfungen ausgestattet um einen Buffer-Overflow verhindern zu können.

Die Funktionen vielleicht schon aber was du vorher als Programmierer bzw Anwender
der Funktionen mit deiner Software anstellst da haben die Funktionen leider keinen
Einfluss drauf, und es passiert immer wieder das du zu wenig Speicher allokierst
oder ungenau programmierst, und im döfsten Fall findest du solche Fehler nicht mal
beim Testen sie wirken sich erst später aus. Wenn du von vorneherein die STL
benutzt kann sowas eben nicht mehr passieren, da sie extra auf Sicherheit designed
ist. Und es ist schon irgendwie sicherer und komfortabler einen string zu benutzen,
statt eines char Pointers bzw eines char Arrays.
In Punkto Performance kann ich dazu sagen das es bei den heutigen Rechnern
kaum noch eine Rolle spielen sollte und wenn man mal Echtzeit Anwendungen brauch
hat man immer noch die Möglichkeit wieder auf die guten alten C-Funktionen zurück
zugreifen.
Der Mensch besitzt die Faehigkeit zum abstrakten Denken, wieso soll er dies nicht
auch umsetzen, anstatt immer nur auf einer Ebene zu bleiben?

In diesem Sinne

Gruß

RedWing
 
Zurück