fopen ergibt <Schlechtes Ptr>



  • Hallo wie sollen für die Schule ein kleines Programm schreiben, es soll 2 Dateien vergleichen und ausgeben in welchen Zeilen welche Zeichen unterschidlich sind.

    Das ist mein Programm:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    FILE *OpenFile(char *sFilename);
    int GetFileSize(FILE *file);
    char *ReadFile(FILE *file, int iSize);
    
    int main(int argc, char **argv)
    {
    	if(argc < 3)
    	{
    		printf("Sie muessen 2 Dateien übergeben.");
    		system("pause");
    		return 1;
    	}
    	else
    	{
    		FILE *file1 = OpenFile(argv[1]); //Datei1 öffnen
    		FILE *file2 = OpenFile(argv[2]); //Datei2 öffnen
    
    		int iFileSize1 = GetFileSize(file1); //Größe der 1. Datei ermitteln
    		int iFileSize2 = GetFileSize(file2); //Größe der 2. Datei ermitteln
    		int iFileSize = 0;					 //Größe der kleinsten Datei
    
    		//Größe der kleinsten Datei ermitteln
    		if(iFileSize1 > iFileSize2)
    			iSize = iFileSize1;
    		else if(iFileSize1 < iFileSize2)
    			iSize = iFileSize2;
    		else
    			iSize = iFileSize1;
    
    		char *cFile1 = ReadFile(file1, iFileSize); //1. Datei lesen
    		char *cFile2 = ReadFile(file2, iFileSize); //2. Datei lesen
    	}
    
    	return 0;
    }
    
    FILE* OpenFile(char *sFilename)
    {
    	FILE *file = fopen(sFilename, "r"); //Date öffnen
    
    	//Überprüfen ob die Datei geöffnet werden konnte.
    	if(file == NULL)
    	{
    		printf("Die Datei: '%s' konnte nicht geoffnet werden", sFilename);
    		perror(sFilename);
    		exit(1);
    	}
    
    	return file;
    }
    
    int GetFileSize(FILE *file)
    {
    	int iFileSize = 0;
    	while( (fgetc(file)) != EOF )
    		iFileSize++;
    
    	return iFileSize;
    }
    
    char *ReadFile(FILE *file, int iSize)
    {
    	char *sFile = malloc(sizeof(char) * iSize);
    	char ch;
    
    	//Überprüfen ob der Speicherplatz angelegt wurde.
    	if(sFile == NULL)
    	{
    		printf("Der Speicherplatz konnte nicht angelegt werden.");
    		perror(sFile);
    		exit(2);
    	}
    
    	sFile = ""; //Zeichenkette leeren.
    
    	//Datei lesen.
    	while( (ch = fgetc(file)) != EOF )
    	{
    		strcat(sFile, ch);
    	}
    
    	return sFile;
    }
    

    Jetzt habe ich aber ein Problem. an den Stellen:

    FILE *file1 = OpenFile(argv[1]); //Datei1 öffnen
    FILE *file2 = OpenFile(argv[2]); //Datei2 öffnen

    bekomme ich <Schlechtes Ptr>, die Dateien sind aber vorhanden und es sind auch normale Textdateien, mit dem Debugger habe ich festgestellt das sogar schon fopen einen <Schlechtes Ptr> zurück gibt, also ich finde den Fehler nicht.

    Ich habe auch versucht fopen direkt in die main-Funktionien zu schreiben dass ergibt aber ebenfalls einen <Schlechtes Ptr>



  • Hallo,

    wie wird das Programm gestartet, wie sieht die Kommandozeile aus? Du kannst leicht testen, ob es an den Dateien liegt, in dem du den ganzen Pfad angibst:

    programm.exe "C:\pfad\zur\datei.txt" "C:\pfad\zur\datei2.txt"

    MfG,

    Probe-Nutzer



  • Ja beide Dateien liegen auf C: programm.exe C:\Test1.txt C:\Test2.txt und auf C habe ich volle rechte



  • Funktioniert denn irgendwas an dem Programm nicht? Oder lässt Du Dich nur vom Debugger verunsichern?



  • Ok, aber das Programm gibt doch nicht den Fehler aus, den du hiermit:

    if(file == NULL)
        {
            printf("Die Datei: '%s' konnte nicht geoffnet werden", sFilename);
            perror(sFilename);
            exit(1);
        }
    

    anzeigst, oder?

    MfG,

    Probe-Nutzer



  • Nein einen fehler gibt es nicht, ich bin auch das ganze Programm mit dem Debugger durchgegangen, er überpringt die if Abfrage, achja ich habe noch was vergessen,
    an der Stelle:
    int iFileSize1 = GetFileSize(file1); //Größe der 1. Datei ermitteln
    int iFileSize2 = GetFileSize(file2); //Größe der 2. Datei ermitteln

    sind die beiden FILE Pointer mit Datenmüll gefüllt.



  • Du darfst dich hier wirklich nicht auf den Debugger verlassen. Wenn nicht NULL zurückgegeben wird, dann ist der FILE* gültig. Und da zwischen den Aufrufen von OpenFile und GetFileSize keine anderen Anweisungen stehen, ist auch da kein Problem zu erwarten.

    Aber in der Funktion ReadFile gibt es Fehler:

    sFile = ""; //Zeichenkette leeren.
    

    nicht ok, damit wird nicht mehr der von malloc besorgte Speicherplatz genutzt. Wenn du Nullen willst, dann z.B. so:

    memset(sFile, 0, iSize);
    

    Auch das:

    strcat(sFile, ch);
    

    passt nicht, denn strcat erwartet einen char*, kein char, als zweites Argument. Hier überlasse ich dir die Lösung dieses (kleinen) Problems.

    Und hier:

    if(iFileSize1 > iFileSize2)
                iSize = iFileSize1;
            else if(iFileSize1 < iFileSize2)
                iSize = iFileSize2;
            else
                iSize = iFileSize1;
    

    sollte iSize unbekannt sein.

    MfG,

    Probe-Nutzer



  • Danke aber in ReadFile() überpringt er auch die while-Schleife weil in file datenmist drin ist und fgetc direkt -1 zurück gibt.
    Also bis zum strcat komme ich garnicht.



  • Vergiss den Datenmist in file, das ist nicht der Grund. Aber wenn die Funktion GetFileSize abgearbeitet ist, dann steht der Lesezeiger der Dateien natürlich auf EOF(-1), du musst dann, wenn erneut von Anfang an gelesen werden soll, den Zeiger zurück setzen, dafür gibt es rewind:

    int iFileSize1 = GetFileSize(file1); //Größe der 1. Datei ermitteln
            int iFileSize2 = GetFileSize(file2); //Größe der 2. Datei ermitteln
            int iFileSize = 0;                     //Größe der kleinsten Datei
    
            //Größe der kleinsten Datei ermitteln
            if(iFileSize1 > iFileSize2)
                iSize = iFileSize1;
            else if(iFileSize1 < iFileSize2)
                iSize = iFileSize2;
            else
                iSize = iFileSize1;
    
            int iFileSize1 = GetFileSize(file1); //Größe der 1. Datei ermitteln
            int iFileSize2 = GetFileSize(file2); //Größe der 2. Datei ermitteln
            int iFileSize = 0;                     //Größe der kleinsten Datei
    
            //Größe der kleinsten Datei ermitteln
            if(iFileSize1 > iFileSize2)
                iSize = iFileSize1;
            else if(iFileSize1 < iFileSize2)
                iSize = iFileSize2;
            else
                iSize = iFileSize1;
    
            rewind(file1);
            rewind(file2);
    
            char *cFile1 = ReadFile(file1, iFileSize); //1. Datei lesen
            char *cFile2 = ReadFile(file2, iFileSize); //2. Datei lesen
    

    Habe ich auch erst jetzt nach genauerem Hinsehen bemerkt... 🙂

    MfG,

    Probe-Nutzer



  • Ach: Und fgetc liefert immernoch int, damit lassen sich auch das Byte 0xff und der Kennzeichner EOF auseinanderhalten 🙂



  • Ah bis jetzt geht es, danke.
    Aber jetzt habe ich das Problem mit dem strcat, hier stürzt das Programm ab:

    Unbehandelte Ausnahme bei 0x651af693 (msvcr90d.dll) in DateiVergleichen.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000048.
    

    Aber ich kenne keine anderen Funktion um was an einen string anzuhängen.

    So Problem gelöst, fgets() ist mein Freund 😃


Anmelden zum Antworten