Kleines Problem mit FILE Pointern



  • Ja, das heißt ja auch "arr = realloc(arr,(i+1)*sizeof(int));".

    Und das arr++ solltest du weglassen und stattdessen lieber über einen Index auf das letzte Element zugreifen:

    i=0;
    while(!feof(fp))
    {
      arr = realloc(arr,(i+1)*sizeof(int));
      fscanf(fd,"%d",arr[i]);
      ++i;
    }
    


  • #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
    	FILE *fp;
    	int anz, i = 0;
    	int *arr;
    	fp = fopen("D:\\Studium\\Informatik 2\\Labor\\Aufgabe 3.1\\qsort.txt","r+b");
    	arr = calloc(1, sizeof(int));
    
    		fscanf(fp, "%d", arr);
    		arr = realloc(arr, 2*sizeof(int));
    		arr[i+1];
    		while(!feof(fp))
    		{
    			fscanf(fp, "%d", arr[i]);
    			arr = realloc(arr, 3*sizeof(int));
    			//arr = realloc(arr,(i+1)*sizeof(int));
    			i++;
    			//arr++;
    		}
    
    	return 0;
    }
    

    so bin jetzt am verzweifeln, hab das jetzt mit dem Index versucht, er stürzt jetzt in der while schleife beim ersten durchlauf beim fscanf befehl ab, wegen dem Index. Ohne ihn gibts nette speicherfehler beim realloc in der while. das erste Realloc oben funktioniert...ich dreh noch durch... brauch jetzt erstmal ne pause...sitz hier seit 7 uhr und programmier...kopf ist jetzt echt voll 🙂



  • Sorry, mein Fehler - fscanf() braucht ja die Adresse - also muß das "&arr[i]" oder "arr+i" heißen.

    (und mit der Speichervergrößerung solltest du mal auf die Reihenfolge achten - erst realloc(), dann fscanf(), sonst schreibst du über das Ende deiner Daten hinaus)



  • ne das ist schon ok so, ich hol ja erst mit calloc den speicher, dann erstes fscanf, dann realloc den speicher vergrößern. jetzt in der while wieder fscanf und dann erneut die vergrößerung

    so siehts jetzt aus

    http://img50.imageshack.us/img50/3236/untitled2pg2.th.jpg

    muss ich beim realloc dann auch mit dem indexs arbeiten? eigentlich schon oder?



  • Ich hab den Thread mal in Ruhe durchgelesen und hoffe das ist was du brauchst:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        FILE *fp = NULL;
        int *array = NULL, i = 0, j = 0;
        if((fp = fopen("D:\\Studium\\Informatik 2\\Labor\\Aufgabe 3.1\\qsort.txt","r+b")) == NULL)
            return EXIT_FAILURE;
        do
        {
            if(array == NULL)
            {
                if((array = (int *)malloc(sizeof(int))) == NULL)
                    return EXIT_FAILURE;
            }
            else
            {
                if((array = (int *)realloc(array, ++i * sizeof(int))) == NULL)
                    return EXIT_FAILURE;
            }
        }
        while((fscanf(fp, "%d", &array[i])) != EOF);
        fclose(fp);
        fp = NULL;
        for(j = 0; j < i; j++)
            printf("Wert: %d\n", array[j]);
        free(array);
        array = NULL;
        return EXIT_SUCCESS;
    }
    

    Viel Spaß damit 😉



  • wird durch das ++i der Index auch schon hochgezählt? ja oder?
    Danke für den Code 😃



  • mazeli schrieb:

    wird durch das ++i der Index auch schon hochgezählt? ja oder?

    Geneauso ist es.



  • hmm also das programm scheint so nicht zu funktionieren, zumindest gibt er mir nur die erste zahl richtig aus und dann nur noch irgendwelche werte



  • meine Variante:

    #include <stdio.h> 
    #include <stdlib.h> 
    
    #define pfad "D:\\Studium\\Informatik 2\\Labor\\Aufgabe 3.1\\qsort.txt"
    int main() 
    { 
        FILE* fp;   
        int tmp, temp;
        int* array;     
    
        if ((fp = fopen(pfad,"r+b")) == NULL) 
            return EXIT_FAILURE; 
        for (tmp = 0; fscanf(fp, "%d", &temp) != EOF; tmp++); 
        fclose(fp);
    
        array = (int*) malloc(tmp*sizeof(int));
    
        if ((fp = fopen(pfad,"r+b")) == NULL) 
            return EXIT_FAILURE; 
        for (tmp = 0; fscanf(fp, "%d", &array[tmp]) != EOF; tmp++) 
            printf("Wert: %d\n", array[tmp]); 
    
        fclose(fp);
        free(array); 
        array = NULL; 
        return EXIT_SUCCESS; 
    }
    

    🕶



  • Joar Danke, die tut 😃

    aber möchte gern wissen was bei der obigen der Fehler ist



  • habs debuggt und korrigiert - jetzt läufts

    #include <stdio.h> 
    #include <stdlib.h> 
    
    int main(void) 
    { 
        FILE *fp = NULL; 
        int *array = NULL, i = 1, j = 0; 
        if((fp = fopen("D:\\Studium\\Informatik 2\\Labor\\Aufgabe 3.1\\qsort.txt","r+b")) == NULL) 
            return EXIT_FAILURE; 
        do 
        { 
            if(array == NULL) 
            { 
                if((array = (int *)malloc(sizeof(int))) == NULL) 
                    return EXIT_FAILURE; 
            } 
            else 
            { 
                if((array = (int *)realloc(array, ++i * sizeof(int))) == NULL) 
                    return EXIT_FAILURE; 
            } 
        } 
        while((fscanf(fp, "%d", &array[i-1])) != EOF); 
        fclose(fp); 
        fp = NULL; 
        for(j = 0; j < i-1; j++) 
            printf("Wert: %d\n", array[j]); 
        free(array); 
        array = NULL; 
        return EXIT_SUCCESS; 
    }
    

    🕶 🕶



  • Vielen Dank euch allen für die Hilfe

    hier der fertige Code mit Qsort.

    #include <stdio.h>
    #include <stdlib.h>
    #include "compare.h"
    
    int main(void)
    {
    	FILE *fp = NULL;
    	int anz = 0, i = 1, y = 0;
    	int *arr = NULL;
    	if((fp = fopen("D:\\Studium\\Informatik 2\\Labor\\Aufgabe 3.1\\qsort.txt","r+b")) == NULL)
    		return EXIT_FAILURE;
    
    	do
    	{
    		if(arr == NULL)
    		{
    			if((arr = (int *)malloc(sizeof(int))) == NULL)
    			return EXIT_FAILURE;
    		}
    		else
    		{
    			if((arr = (int *)realloc(arr, ++i * sizeof(int))) == NULL)
    				return EXIT_FAILURE;
    		}
    	}while((fscanf(fp, "%d", &arr[i - 1])) != EOF);
    	fclose(fp);
    	fp = NULL;
    	printf("\nEingelesene unsortierte Werte: \n\n");
    	for(y = 0; y < i-1; y++)
    		printf("%d ", arr[y]);
    
    	printf("\n\nEingelesene sortierte Werte: \n\n");
    
    	qsort(arr, i-1, sizeof(int), compare_int);
    
    	for(y = 0; y < i-1; y++)
    		printf("%d ", arr[y]);
    
    	free(arr);
    	return EXIT_SUCCESS;
    }
    
    #include "compare.h"
    
    int compare_int(const void *ptr1, const void *ptr2)
    {
    	int ret, z1, z2;
    
    	z1 = *(int *) ptr1;	/* Cast auf Integer */
    	z2 = *(int *) ptr2;
    
    	if (z1 < z2)
    		ret = -1;
    	else if(z1 == z2)
    		ret = 0;
    	else
    		ret = 1;
    	return ret;
    }
    
    extern int compare_int(const void *, const void *);
    


  • Den Returnwert in der Vergleichsfunktion kannst du im Falle von Integern auch etwas kürzer schreiben:

    return (z1 - z2);
    

    Damit sparst du dir die Vergleiche. Für den allgemeineren Fall (z.B. Strukturen sortieren) gilt das natürlich nicht.



  • joar stimmt, aber in der Aufgabe war es so vorgegeben.

    Naja hab jetzt grad en anderes problem.

    Wollte das selbe Programm jetzt mit nem Modul erweitern welches ein dynamisch erzeugtes INT Array mit zufallswerten füllt und sortieren lässt (Modul ist vorhanden un funktioniert)

    jetzt wollte ich natürlich mein altes Programm nicht löschen und deshalb die alte Funktion mit der Datei in ein extra Modul packen, so als übung nebenbei. Natürlich klappt es nicht 😃

    in der Funktion create_file kann ich das eingelesene Array ausgeben, aber in der main selbst stürtzt er beim printf ab.

    Denke mal das ich was mit den Arrays/Pointer was falschgemacht habe.
    Habe das Thema Pointer wohl immer noch net richtig im Griff...

    achso noch ne kleine Frage: Ich suche ein schönes Buch zum Thema c / c++, so ne art referenz wo alle funktionen schön beschrieben sind, und natürlich wo auch noch normale Erklärungen hat, halt ein gutes Buch zum Nachschlagen aber auch neue Themen lernen.

    Bissle Farbe sollte auch vorhanden sein, einfach nur schwarzweiß text ist bei mir irgendwie wirkungslos 😃

    Könnt ihr da was empfehlen?

    bzw hier mal der Code:

    Inhalt der main.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include "compare.h"
    #include "file.h"
    #include "array.h"
    
    int main(void)
    {
    
    	int anz = 0, i = 0, y = 0;
    	int *arrr = NULL;
    
    	i = create_file(&arrr);
    
    	printf("\nEingelesene unsortierte Werte: \n\n");
    	for(y = 0; y < i-1; y++)
    		printf("%d ", arrr[y]);
    
    	printf("\n\nEingelesene sortierte Werte: \n\n");
    
    	qsort(arrr, i-1, sizeof(int), compare_int);
    
    	for(y = 0; y < i-1; y++)
    		printf("%d ", arrr[y]);
    
    	//free(arrr);
    	return EXIT_SUCCESS;
    }
    

    Inhalt der file.c

    #include "file.h"
    #include <stdlib.h>
    #include <stdio.h>
    
    int create_file(int *Aptr)
    {
    	int *arr = NULL; //(int *) calloc(sizeof(int), max);
    	int *tmp = arr;
    	int i = 0, y = 0;
    	FILE *fp = NULL;
    
    	if((fp = fopen("D:\\Studium\\Informatik 2\\Labor\\Aufgabe 3.1\\qsort.txt","r+b")) == NULL)
    		return EXIT_FAILURE;
    
    	do
    	{
    		if(arr == NULL)
    		{
    			if((arr = (int *)malloc(sizeof(int))) == NULL)
    				return EXIT_FAILURE;
    		}
    		else
    		{
    			if((arr = (int *)realloc(arr, ++i * sizeof(int))) == NULL)
    				return EXIT_FAILURE;
    		}
    	}while((fscanf(fp, "%d", &arr[i - 1])) != EOF);
    
    	/*printf("\nEingelesene unsortierte Werte: \n\n");
    	for(y = 0; y < i-1; y++)
    		printf("%d ", arr[y]);*/
    	*Aptr = tmp;
    
    	fclose(fp);
    	fp = NULL;
    
    	return i;
    
    }
    

    Inhalt der file.h

    int create_file(int *);
    

    inhalt der compare.c

    #include "compare.h"
    
    int compare_int(const void *ptr1, const void *ptr2)
    {
    	int ret, z1, z2;
    
    	z1 = *(int *) ptr1;	/* Cast auf Integer */
    	z2 = *(int *) ptr2;
    
    	if (z1 < z2)
    		ret = -1;
    	else if(z1 == z2)
    		ret = 0;
    	else
    		ret = 1;
    	return ret;
    }
    

    compare.h

    extern int compare_int(const void *, const void *);
    

    Also er stürzt beim ersten printf in der main ab.

    Nehme an weil im Array nix steht.



  • Ja, C übergibt Parameter als Kopie, das heißt eine Zuweisung in der Funktion wirkt sich nicht auf das Hauptprogramm aus. Da brauchst du schon Zeiger auf Zeiger:

    int create(int** Aptr)
    {
      int* tmp=NULL;
      ...
      *Aptr = tmp;
    }
    
    ...
    int* array;
    create(&array);
    

    (ein weiterer Fehler: Du arbeitest in der Funktion die ganze Zeit mit arr und gibst am Ende tmp zurück - der steht aber nach der ersten Zuweisung weiterhin auf NULL)

    PS: Übrigens kann realloc() auch einen NULL-Zeiger übergeben bekommen, also ist die Fallunterscheidung "if(arr==NULL)" unnötig.



  • hmm klingt schon logisch,

    aber wieso funktioniert das dann hier?

    array.c

    #include <stdlib.h>
    #include <stdio.h>
    #include "array.h"
    #include <time.h>
    
    void scanArray(unsigned int max, int *Aptr, int *anz)
    {
    	int i = 0;
    	int *tmp_arr = (int *) calloc(sizeof(int), max);
    	int *tmp = tmp_arr;
    
    	printf("\nBitte Werte eingeben: ");
    
    	while(i < max)
    	{
    		*anz = scanf("%i", tmp_arr);
    
    		if(*anz != 1)
    			break;
    		if(*anz >= max)
    			break;
    		i++;
    		(*anz)++;
    		tmp_arr++;
    	}
    	*Aptr = tmp;
    	free(tmp_arr);
    }
    
    void fillArray(unsigned int max, int *Aptr, int *anz)
    {
    	int *tmp_arr = (int *) calloc(sizeof(int), max);
    	int *tmp;
    	int i = 0;
    
    	tmp = tmp_arr;
    
    	srand(time(NULL));
    
    	*anz = rand()%max;
    
    	for(i = 0; i < *anz; i++)
    	{
    		tmp_arr[i] = rand()%max;
    	}
    	*Aptr = tmp;
    }
    
    void printArray(unsigned int max, int *Aptr, int *anz)
    {
    	int z = 0;
    
    	printf("\nEingelesene Werte: \n\n");
    
    	for(z = 0; z < max; z++)
    	{
    		if(z % 8 == 0)
    			printf("\n");
    		printf("%6i", Aptr[z]);
    	}
    
    }
    

    main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "array.h"
    #include "average.h"
    
    #define MAX 10
    
    int main(void)
    {
    	int *arr;
    	int n = 0;
    	double x = 0;
    
    	//scanArray(MAX, &arr, &n);
    	fillArray(MAX, &arr, &n);
    	printArray(MAX, arr, &n);
    	//x = average(MAX, arr, &n);
    	//printf("\n\nMittelwert: %lf", x);
    	return EXIT_SUCCESS;
    }
    

    hier übergebe ich ja auch eine Kopie an die Funktion, kann aber dann in einer anderen funktion das array mit dem Inhalt ausgeben

    gnaa das zeigt mir eindeutig das ich Zeiger immer noch nicht verstanden habe 😞



  • Hast du jetzt nur beim Abtippen einen Stern vergessen oder übergibst du wirklich einen int** (&arr) als int* (APtr)? Wenn ja, sollte dich eigentlich dein Compiler darauf aufmerksam machen.

    Ansonsten beachte mal die Reihenfolge der Zuweisungen:

    tmp = arr;
    arr = malloc(...);
    ...
    *Aptr = tmp;
    
    //vs
    
    arr = malloc(...);
    tmp = arr;
    ...
    *Aptr = tmp;
    

    (wobei die Variable tmp sowieso überflüssig ist - da du innerhalb der Funktion mit 'arr' arbeitest, reicht auch ein "*Aptr = arr;" am Ende aus)



  • ne hab nix vergessen, ist genauso wie es dort steht...und funktioniert ja auch



  • OK, dann langsam: Du hast im Hauptprogramm einen int* namens arr und übergibst deiner Funktion dessen Adresse (das wäre ein int**). Die Funktion nimmt jedoch ein int* (und rechnet dann seltsamerweise damit so, als ob es ein int** wäre) - da hängt es dann von deinem Glück und dem Compiler ab, ob das funktioniert.



  • hmm ich raff das net mit pointern, ich übergeben die Adresse meines Array oder?
    wenn ich jetzt nur (arr) und nicht (&arr) übergeben hätte, dann würde ich ja einen Pointer auf das erste Element übergeben oder?

    Hmm also das Programm an sich ist falsch aber funktioniert seltsamerweiße?

    ps: Kannst en gutes C Buch empfehlen?


Anmelden zum Antworten