dateien auslesen_vergleichen_hier stimmt was nicht!?



  • @chille07:

    das mit dem else...haste recht! ist besser so!
    zu memcmp:

    "
    memcmp
    Compare characters in two buffers.

    int memcmp( const void *buf1, const void *buf2, size_t count );

    ...
    "
    aus dem msdn...

    die beiden dateien werden main() durch draufziehen auf die *.exe übergeben!
    sie sind also noch nicht vorhanden...jedenfalls kennt das programm sie NOCH nicht! die dateien stehen dann in argv[1] und argv[2].also müsstest du beim debuggen die dateien vorher irgendwo festlegen...geht bestimmt in den einstellungen irgendwo?!
    danke



  • bin mir nicht sicher, wie das main auf !!!2!!! dateien gleichzeitig reagiert...

    versuch mal die dateien mit KONSTANTEN zu öffnen...

    bei den einstellungen brauchst du nichts verändern!
    einfach:

    int main(int argc, char *argv[]) //....
    

    PS.: könntest ja die dateigröße beider dateien herausfinden, vergleichen.. (wenn ungleich... datei anders)
    anschliessend(wenn vorheriges gleich) jedes zeichen einzeln vergleichen (char)
    und fertig, wenn du willst kannst du auch buffer verwenden...

    mfG (c)h



  • 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



  • @spjoe:

    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???



  • @hotspot

    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


  • Mod

    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


  • Mod

    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 😉


Anmelden zum Antworten