dateien auslesen_vergleichen_hier stimmt was nicht!?
-
das mit den 2 dateien und der main() geht doch...das war nie das problem!
und die zeichen einzeln auslesen macht mir keinen sinn, da er doch auch "buffer-weise" vergleichen kann!
das geht glaub ich schneller?!
und das mit vorher die größe der dateien abfragen halte ich auch nicht für sinnvoll, da das programm ja eh abbricht, wenn in den ersten 1024byte unterscheide aufgetaucht sind...das wär nur mehr schreibaufwand!
und so, wie das programm jetzt ist, funktioniert es und gut! man könnte sicherlich noch optimieren, aber ich wollte ja einfach nur, dass es richtig funktioniert!
danke
-
guten morgen und ein gesubdes neues jahr!
hmm, ich bin gard über mein programm gestolpert, weil es doch nicht so funktiniert, wie ich es mir vorgestellt habe!
ich habe schon begonnen es zu debuggen, aber ch weiß jetzt ehrlich gesagt nicht, was der fehler ist! der gehler liegt irgendwo bei der funktion memcmp()zum fehler:
bei "kleinen" dateien (z.b. *.txt) geht es, aber wenn ich eine ewas größere nehme dann nicht! ich habe mal eine *.pdf und eine kopie derselben datei verglichen, und sie sind angeblich NICHT gleich, was ja quatsch ist!wen jemand zeit und lust hat, dann möge er sich doch bitte mal den code anschauen, und mir helfen! ich weiß nicht, wie ich da jetzt ran gehen soll!
danke
hier der code:
#include <stdio.h> #include <conio.h> #include <windows.h> #include <string.h> #include "my_color_console.h" typedef char buffer[1024]; //maximal 10 dateien vergleichbar #define max_dat 10 int main(int argc, char *argv[]) { /* argv[0] enthält programmname (== compare_files.exe) argv[1] enthält dateiname_1 argv[2] enthält dateiname_2 ... */ int x[max_dat]; //länge auf null setzen for (int index0=0; index0 < 10; ++index0) { x[index0]=0; } int index1; int cmp = 0; int anzahl = 0; FILE *fp[max_dat]; buffer buffer_1[max_dat]; /* vordergrundfarbe auf weiß hell setzen */ SetColor(FG_R | FG_G | FG_B | FG_Int); anzahl = (argc-1); printf("anzahl der uebergebenen dateien: %d\n", anzahl); //gibt den pfad aller übergebenen dateien an for(index1 = 0; index1 < anzahl; index1++) { printf("\npfad von datei %d: %s", (index1+1), argv[index1+1]); } //öffnet alle überegebenen dateien for(index1 = 0; index1 < anzahl; index1++) { fp[index1] = fopen(argv[index1+1],"rb"); } printf("\n"); /* liest alle übergebenen dateien paketweise ein */ for(index1 = 0; index1 < anzahl; index1++) { do { x[index1] += fread(buffer_1[index1],1,1024,fp[index1]); } while(!feof(fp[index1])); } /* vergleicht alle eingelesenene dateien */ for(index1 = 0; index1 < (anzahl-1); index1++) { int a = (memcmp(buffer_1[index1],buffer_1[index1+1],x[index1])); printf("%d\n", a); } /* vergleicht alle eingelesenene dateien */ /* for(index1 = 0; index1 < (anzahl-1); index1++) { if( (x[index1] != x[index1+1]) || (memcmp(buffer_1[index1],buffer_1[index1+1],x[index1]) != 0) ) { cmp = 1; } } */ /* gibt länge der dateien aus */ for(index1 = 0; index1 < anzahl; index1++) { printf("\nlaenge der datei %d: %d", (index1+1), x[index1]); } //ausgabe des vergleiches if(cmp == 1) { printf("\n\nDie Dateien sind "); SetColor(FG_R | FG_Int); printf("nicht gleich.\n"); SetColor(FG_R | FG_G | FG_B | FG_Int); } else { printf("\n\nDie Dateien sind "); SetColor(FG_R | FG_Int); printf("gleich.\n"); SetColor(FG_R | FG_G | FG_B | FG_Int); } //schließt alle übergebenen dateien wieder for(index1 = 0; index1 <= (anzahl-1); index1++) { fclose(fp[index1]); } printf("\n\nPress any key to exit!"); getch(); return 0; }
für fragen bezüglich des codes, bitte her damit!
DANKE
-
Ich würde beim auslesen eine verschachtelte schleife machen und sobald etwas ungleich ist abbrechen. Wenn du nicht abbrechen willst vieleicht weil du später die unterschiede zusammen zählen willst ist das auch okay.
Und ein sehr grober fehler ist die beim einlesen passiert du bekommst immer nur die letzt 1024 byte der datei zu lesen (du überschreibst die alten im buffer).Bsp code für das einlesen
/* liest alle übergebenen dateien paketweise ein */ for(index1 = 0; index1 < anzahl-1; index1++) { char buffer1[1024]; char buffer2[1024]; do { x[index1] += fread(buffer1,1,1024,fp[index1]); x[index1+1] += fread(buffer2,1,1024,fp[index1+1]); if(memcmp(buffer1,buffer2,(strlen(buffer1)>strlen(buffer2)) ? strlen(buffer1) : strlen(buffer2)) != 0); cmp = 1; } while(!feof(fp[index1]) && !feof(fp[index1+1]) && cmp == 0); }
bei dieser Lösung fällt auch der gr0ße globale buffer weg!
mfg
-
gut, ich möchte echt nicht meckern, aber hast du deinen code vorher mal ausprobiert? der geht nämlich auch nicht!
die sache mit dem, dass nur die letzten 1024bytes eingelesen werden, ist richtig!
den selben fehler hab ich schonmal gemacht! siehe oben...sehr dämlich von mir...aber selbst wenn, dann müsste er doch bei zwei identischen dateien( datei+kopie derselben..) trotzdem richtig vergleichen, stimmts?
er vergleicht dateien bis einschließlich 1024 bytes richtig! aber größere halt nicht?! woran iegt das!? hat jemand ne ahnung?
wie kriege ich es hin, dass ich die gesamte datei auf einmal einlesen kann? ohne jetzt den buffer von 1024 auf was weiß ich hochzusetzten.
danke schonmal
//edit
wenn ich es so mache:
...
// liest alle übergebenen dateien paketweise ein for(index1 = 0; index1 < anzahl-1; index1++) { do { x[index1] += fread(buffer1,1,1024,fp[index1]); x[index1+1] += fread(buffer2,1,1024,fp[index1+1]); if(x[index1] != x[index1+1] || (memcmp(buffer1,buffer2,1024) != 0)) cmp = 1; } while(!feof(fp[index1]) && !feof(fp[index1+1]) && cmp == 0); }
...
dann vergleicht er mir alle dateien kleiner als 1024 bytes falsch, aber die, die größer sind, werden richtig verglichen...also ich finde das sehr merkwürdig!
warum???
-
Getest hab ich den code nicht.
Syntax fehler es keiner drin.
Symantischer fehler kann sein bin mir aber fast sicher dass das richtig ist was ich gemacht habe.Alles auf einmal einlesen ist vileicht nicht so gut aber ich schreib dir eine möglichkeit wie das geht.(in 4096 byte blöcken hast du beim fat system meiste performance)
fseek( file, 0, SEEK_END ); //Dateizeiger ans Ende setzen size_t fileSize= ftell( file ); //Dateizeiger abfragen buffer = (char*)malloc(filesize);
mfg
-
@hotspot
Warum machst du es dir überhaupt so schwer und liest die Datei in Blöcken?? Les hald einfach jedes Zeichen einzeln ein und vergleiche es. Dann kann deine Datei auch 20 Gb groß sein und es ist kein Problem.Warum dein Vergleich nicht funktioniert, ist ganz einfach erklärt. Du initialisierst deinen Buffer nicht! Und memcmp() vergleicht soviele Zeichen, wie du angibst und das sind nun mal 1024 und nicht soviele, wie du eigentlich eingelesen hast.
-
du solltest den speicherbereich nur vergleichen, wenn beide bereiche gleich groß sind.
mfG (c)h
-
chille07 schrieb:
du solltest den speicherbereich nur vergleichen, wenn beide bereiche gleich groß sind.
mfG (c)h
das macht er doch schon.
-
@AJ:
danke, das hat geholfen...jetzt macht erwenigstens schon mal einen teil von dem, was er soll!ich habe aber noch ein anderes problem:
ich möchte ja auch mehr als 2 dateien miteinander vergleichen können...
obwohl ich gleiche dateien erzeigt habe (3 *.txt) und in den debug-einstellungen mit eingebunden habe, erkennt er die gleichheit nicht!beim debuggen habe ich folgendes festgestellt:
er liest die ersten beiden dateien richtig ein...
er vergleicht die ersten beiden dateien richtig...beim zweiten durchlauf der äussersten for-schleife (ab zeile 74) wird NICHT in den buffer_1 geschrieben, aber in den buffer_2...
--> damit haben beide unterschiedliche länge, und die abbruchbedingung ist erfüllt!hab ich noch nen denkfehler, oder warum macht er das nicht?
wäre schön, wenn mir noch jemand helfen könnte.vielen dank schonmal!
hier mal der code: wichtig sind die zeilen ab zeile 74...
#include <stdio.h> #include <conio.h> #include <windows.h> //#include "my_color_console.h" //maximal 10 dateien vergleichbar #define max_dat 10 //ausgabe für gleiche dateien void gleich(void) { printf("\n\nDie Dateien sind "); // SetColor(FG_R | FG_Int); printf("gleich.\n"); // SetColor(FG_R | FG_G | FG_B | FG_Int); } //ausgabe für ungleiche dateien void ungleich(int a) { printf("\n\nDie Dateien sind "); // SetColor(FG_R | FG_Int); printf("nicht gleich.\n"); // SetColor(FG_R | FG_G | FG_B | FG_Int); printf("\nAbbruch der testung nach %d bytes.", a); } //main() int main(int argc, char *argv[]) { /* argv[0] enthält programmname (== compare_files.exe) argv[1] enthält dateiname_1 argv[2] enthält dateiname_2 ... */ //variablendefinition int x[max_dat], filesize[max_dat], index0, index1, cmp = 0, anzahl = 0; HANDLE hfile[max_dat]; FILE *fp[max_dat]; //SetColor(FG_R | FG_G | FG_B | FG_Int); anzahl = (argc-1); printf("anzahl der uebergebenen dateien: %d\n", anzahl); //gibt den pfad aller übergebenen dateien an for(index1 = 0; index1 < anzahl; index1++) { printf("\npfad von datei %.2d: %s", (index1+1), argv[index1+1]); } printf("\n"); //ermittelt die dateigröße in bytes for(index1 = 0; index1 < anzahl; index1++) { hfile[index1] = CreateFile(argv[index1+1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); filesize[index1] = GetFileSize(hfile[index1], NULL); printf("\ndateigroesse von datei %.2d: %d bytes", (index1+1), filesize[index1]); } //öffnet alle überegebenen dateien for(index1 = 0; index1 < anzahl; index1++) { fp[index1] = fopen(argv[index1+1],"rb"); } //***************** also hier ist zeile 72 ********************************** // liest alle übergebenen dateien zeichenweise ein und vergleicht sie for(index1 = 0; index1 < anzahl-1; index1++) { char buffer_1[] = "0"; char buffer_2[] = "0"; //länge auf null setzen for (index0 = 0; index0 < anzahl; ++index0) { x[index0]=0; } do { x[index1] += fread(buffer_1, 1, 1, fp[index1]); x[index1+1] += fread(buffer_2, 1, 1, fp[index1+1]); if(x[index1] != x[index1+1] || (memcmp(buffer_1, buffer_2, 1) != 0)) cmp = 1; } while(!feof(fp[index1]) && !feof(fp[index1+1]) && cmp == 0); } int a = x[0]; //ausgabe des vergleiches (cmp == 1) ? ungleich(a) : gleich(); //schließt alle übergebenen dateien wieder for(index1 = 0; index1 < anzahl; index1++) { fclose(fp[index1]); } printf("\n\nPress any key to exit!"); getch(); return 0; }
-
du solltest den dateipointer am beginn der forschleife an die anfangsposition setzen.
fseek(FILE*,0,SEEK_SET);
und die vorbelegung von
char buffer_1[] = "0";
würde ich weglassen.
mfG (c)h
-
hotspot schrieb:
hier mal der code: wichtig sind die zeilen ab zeile 74...
jaja.. schön dass wir so genau sehen, wo die zeile 74 ist...
also.. dann schaun wir mal... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ....ganz schön anstrengend, wobei du die zeile mit einem kommentar markieren könntest
-
habs geändert!!!
aber AJ gab mir doch den tipp, den buffer zu initialisieren...und damit geht zumindest mal der vergleich zweier dateien problemlos!
-
initiallisieren kannst du es jedoch auch, ohne eine "0" hineinzuschreiben.
einfach eine \0 an die erste stelle
-
erstmal vielen dak für den tipp mit dem filepointer...jetzt geht es!
das mit dem initialiesieren hab ich aber jetzt nicht ganz geschnallt!
wie meinst du das? wie mache ich das? ich dachte initialisieren heißt, mit nem bestimmten wert belegen...
kannst du mir mal bitte die code-zeile verraten, die du meinst!danke
-
char test[]=""; // würde ein feld mit 1byte anlegen, wert: 0 char test[]={0}; // würde auch ein feld mit 1 byte anlegen, wert: 0 char test[]="0"; // würde ein feld mit 2 byte anlegen, wert= 48,0
... da du immer nur 1 zeichen einliest, würde ich vorschlagen, du verwendest eine der oberen 2 möglichkeiten.
PS.: fread hängt kein \0 an; der zusätzliche speicher wird nicht benötigt
der vergleich vergleicht nur die ersten bytes, dadurch wird die \0 halt ignoriert...nochwas: dein memcmp mit einem byte könntest du durch ein:
(buffer_1==buffer_2)
ersetzen.
-
mal abgesehen davon, dass es mehr schreibaufwand ist, was hätte das für einen vorteil?
danke
-
(buffer_1==buffer_2)
ist, soweit ich das erkennen kann etwas kürzer, und dürfte auch schneller als
(memcmp(buffer_1, buffer_2, 1) != 0))
ablaufen.
und falls du das 1. meinst:
char test[]="";
char test[]="0";
auch hier... mehr schreibaufwand? wohl kaum! speicherplatz? weniger benötigt. (zwar nur 2 bytes, aber ist doch schon ein anfang
)
mfG (c)h
PS.: wenn du richtig gemeint, aber falsch bei mir angekommen ist, kannst du die vergleiche ignorieren
-
gegen gepuffertes vergleichen ist nichts einzuwenden. aber du must dir dann nat. merken, wieviele bytes im jeweiligen lesevorgang gelesen wurden und nicht nur die totale anzahl (bez. du könntest das auch mit %1024 rekonstruieren).
size_t read1, read2; do { read1 = fread( buffer1, 1, 1024, fp[ index1 ] ); read2 = fread( buffer2, 1, 1024, fp[ index1 + 1 ] ); } while( read1 && read1 == read2 && memcmp( buffer1, buffer2, read1 ) == 0 ); cmp = read1 || read2;
ein initialisieren des puffers ist hier gänzlich unnötig. falls dein algorithmus das erfordern sollte, ist wahrcheinlich ein logikfehler drin
-
also wenn ich dich wäre würde ich so den code den du für 2 dateien hast, einfach in eine schleife packen die etwa so ist..
int main(....){ for(int counter=0;counter<argc;counter++){ /*hier dein code*/ //zu beachten: file_1 = argv[counter]; file_2=argv[counter+1]; //und zum schluss: if(nichtgleich){ prinf("Leider nein"); return 0; } }//ende der for prinf("identisch"); return 0; }//end main
-
nickname (höhö, witzbold) schrieb:
also wenn ich dich wäre würde ich ...
... erstmal deutsch lernen?
:p