Auspannen eines Feldes



  • Das funktioniert leider immer noch nicht. Die Fehlermeldung ist unverändert.

    Kurt kannst Du mir einmal erklären - was da passiert. Wie kann ein sizeOf verwendet werden, wenn der Pointer dataBag noch gar nicht zuvor definiert wurde?



  • W2K2005 schrieb:

    Das funktioniert leider immer noch nicht. Die Fehlermeldung ist unverändert.

    Kurt kannst Du mir einmal erklären - was da passiert. Wie kann ein sizeOf verwendet werden, wenn der Pointer dataBag noch gar nicht zuvor definiert wurde?

    Sorry mein Fehler
    muss natürlich

    double **dataBag = (double**) malloc(sizeof(double *) * ydim);
    

    sein
    Kurt



  • Hallo Kurt:

    Super! Jetzt gehts.
    Hättest Du vielleicht noch einen Moment Zeit, um mir zu erklären, was hier passiert. Die Erklärung von c.crackwitz leuchtet mir noch nicht ganz ein.

    1 double **dataBag = (double**) malloc(sizeof(double *) * ydim);
    2 for (i = 0; i < ydim; ++i) 
    3     databag[i] = malloc(sizeof(**databag) * xdim); 
    4 }
    

    Zunächst wird ein Feld von double-Pointern (Dimension: ydim) allokiert.
    - Warum müssen diese von C++ gecastet werden? Crackwitz hat mir geschrieben, dass dies ein schlechter Stil ist.
    - Warum werden in Zeile 1 Pointer allokiert und nicht konventionelle Variablen?
    - **dataBag ist dann ein Pointer auf einen Pointer. Richtig?



  • W2K2005 schrieb:

    - Warum werden in Zeile 1 Pointer allokiert und nicht konventionelle Variablen?

    Weil hinter jedem Element von dataBag ein eigenes SubArray angelegt werden soll - d.h. die Elemente sind Pointer (und werden in Zeile 3 mit Werten gefüllt).

    - **dataBag ist dann ein Pointer auf einen Pointer. Richtig?

    Korrekt.



  • CStoll schrieb:

    - **dataBag ist dann ein Pointer auf einen Pointer. Richtig?

    Korrekt.

    Kommt jetz drauf an welches in

    sizeof(**databag)
    

    ists ein double 😉
    Kurt



  • CStoll schrieb:

    @showme: in C gibt es (noch) kein new 😉

    besser ist das. die heapverwaltung ist eine library und hat in der sprache nix verloren.



  • Hi,

    kannn mir bitte noch einmal jemand helfen. Ich bekomme diese 2D-Feld aus double-Zahlen nicht aufgespannt.

    double **dataBag = (double**) malloc(sizeof(double*) * ydim);
        for (i = 0; i < ydim; ++i) {
    	dataBag[i] = (double*) malloc(sizeof(double) * xdim);
        }
    

    Vielen Dank,

    W2K2005



  • W2K2005 schrieb:

    Ich bekomme diese 2D-Feld aus double-Zahlen nicht aufgespannt.

    Eine ausführliche Fehlerbeschreibung ist immer hilfreich. Deine hat den Informationsgehalt von "geht nicht".

    Der Code sieht doch gut aus. Ich würde allerdings xdim und ydim vertauschen.



  • Wenn ich versuche dem Feld Werte zuzuweisen, dann funktioniert das nur, solange ich die erste Spalte verwende.

    Also:

    double value = 3.14152;
    int i =0, j;
    for (i=0; i<dim; i++) {
      for (j=0; j<xdim; j++) {
         dataBag[i][j] = value;
      }
    }
    

    Soabld i > 0 ist, stehen zwar Werte in der Matrix dataBag aber irgendwie ganz komisch angeordnet....



  • W2K2005 schrieb:

    irgendwie ganz komisch

    Ach so, na dann ist ja alles klar 🙄

    Bitte zeig uns ein kompilierbares Minimalbeispiel, mit "irgendwie ganz komisch".



  • #include <stdio.h>
    #include <stdlib.h>
    
    void main(void) {
    double value = 3.14152;
    
    int i = 0, j;
    int xdim, ydim;
    
    	scanf("%d", &xdim);
    	scanf("%d", &ydim);
    
    	double **dataBag = (double**) malloc(sizeof(double*) * ydim);
        for (i = 0; i < ydim; ++i) {
    		dataBag[i] = (double*) malloc(sizeof(double) * xdim);
        }
    
    	for (i=0; i<ydim; i++) {
    		for (j=0; j<xdim; j++) {
    			dataBag[i][j] = value;
    		}
    	}
    
    	for (i=0; i<ydim; i++) {
    		for (j=0; j<xdim; j++) {
    			printf("%d ", dataBag[i][j]);
    		}
    		printf("\n");
    	}
    }
    


  • double und %d passt nicht zusammen.



  • Stimmt!
    In dem Einfachen Beispiel funktioniert die Speicherallokierung - aber in dem Programm, wo ich das Datenfeld eigentlich brauche, klappt es nicht.
    Hier ist ein Auszug davon. *pList ist eine Liste mit Dateinamen. Diese enthalten Zahlenwerte, die mit der Funktion parse gelesen werden. Wenn parse die Zeile interpretieren konnte, gibt die Funktion den Wert 1 zurück. Solange ich mich in der ersten Zeile (1. Datei) bewege, funktioniert das Programm. Anschließend entsteht der Fehler???

    double **dataBag = (double**) malloc(sizeof(double*) * ydim);
    		for (i = 0; i < ydim; ++i) {
    			dataBag[i] = (double*) malloc(sizeof(double) * xdim);
    		}
    
    		i=0;
    		do {
    			printf("> Scanne %d. Datei: %s\n", i+1, pLIST[i].filename);
    
    			fPtr = fopen(pLIST[i].filename, "r");
    			if (fPtr != NULL) {
    				// Spaltenindex zurücksetzen
    				j=0;
    				while (!feof(fPtr)) {
    					// Textzeile auslesen
    					fgets(string, max, fPtr);
    					RetVal = parse(string, name, &value, unit);
    					if (RetVal == 1) {
    						// Daten ins Feld speichern
    						dataBag[i][j] = value; // Hier entsteht der Fehler mit i=1 und j=0
    						j = j + 1;
    					} else {
    						dataBag[i][j] = 0;  // Hier entsteht der Fehler mit i=1 und j=0
    					}
    				}
    				fclose(fPtr);
    			} else {
    				printf("> Die Datei: %s konnte nicht ge%cffnet werden. Weiter...\n", pLIST[i].filename, 148);
    			} 
    			i=i+1;
    		} while (i < nums);
    

    Das Programm liefert einen Ausnahmefehler, wenn die zweite Quelldatei geöffnet wird und ich versuche auf das Element [1][0] zuzugreifen.



  • Ich vermute, du überschreibst den dataBag-Zeiger, weil du bei einem anderen Array über die Grenzen hinaus schreibst. Möglicherweise ist string nicht groß genug, vielleicht schlägt auch die parse-Funktion über die Stränge.

    Prüf mal den Wert des Zeigers vor fgets, zwischen fgets und parse, und nach parse.



  • Ich schicke mal das ganze Programm.
    In meiner Eingabedatei steht beispielsweise folgender Text:

    1 INTEGRAL DATA
    2 -----------------------------------
    3 PLANE 1M
    4 -----------------------------------
    5 STATIC PRESSURE : 12345.7679543 [Pa] (gfdgdgd)
    6 STATIC PRESSURE : 54321.0 [Pa] (reduced quantity)


    8 ABSOLUTE TOTAL PRESSURE : 8000000.00000 [Pa] (not reduced quantity)
    9 ABSOLUTE TOTAL TEMPERATURE : 400.0000 [K]

    Ich glaube eigentlich nicht, dass ich das Feld sprenge, denn ich lese zuvor die Anzahl der Zeilen aus meiner Datenbasis mit getMaxFileLength ein.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    
    typedef struct tagsLIST{
    	char filename[200];
    	char path[300];
    } cLIST;
    
    int parse(char *string, char *name, double *value, char *unit) {    
    	if (3 == sscanf(string, "%[^:]:%lf [%[^]]", name, value, unit)) {
    		while (strlen(name) && (name[strlen(name)-1] == ' ' ))
    			name[strlen(name)-1]='\0';
    		return 1;
        } else {
           printf("> Error parsing.\n");
           return 0;
        }
    }
    
    int getmaxFileLength(cLIST *pLIST, int nums) {
    	int i, j; 
    	int max = 0;
    	char tmp[512];
    	FILE *fPtr;
    
    	for (i=0; i<=nums; i++) {
    		fPtr = fopen(pLIST[i].filename, "r");
    		if (fPtr != NULL) {
    			// Index auf Null zurücksetzen
    			j = 0;
    			// Datei existiert - ermittle Anzahl der Zeilen
    			while(!feof(fPtr)) {
    				fgets(tmp, 512, fPtr);
    				j = j + 1;
    			}
    
    			if (j > max) {
    				if (max > 0) printf("> ACHTUNG: Die Datei %s besitzt eine andere Zeilenl%cnge.\n           Dies kann zu Problemen f%chren.\n", pLIST[i].filename, 132, 129);
    				max = j;
    			}
    			fclose(fPtr);
    		}
    	} 
    	return max;
    }
    
    void main(void) {
    	const int max = 300;
    
    	int nums, RetVal;
    	int xdim = 0, ydim = 0;
    	int i = 0, j = 0;
    
    	double tmp, value;
    
    	char string[max], output[max];
    	char name[max], unit[50];
    
    	FILE *fPtr;
    
    	printf("--------------------------------------------------------------------------------");
    	printf("|                                                                              |");
    	printf("|                            Datenbasis-Generator                              |");
    	printf("|                                                                              |");
    	printf("--------------------------------------------------------------------------------\n\n");
    
    	do {
    		printf("> Geben Sie die Anzahl der Dateien ein: ");
    		scanf("%d", &nums);
    		if (nums < 0) {
    			printf("> Bitte geben Sie einen ganzzahligen positiven Wert ein.\n\n");
    		}
    	} while (nums < 0);
    	if (nums >= 1) {
    
    		// Ausgabedateiname einlesen
    		printf("> Geben Sie den Ausgabedateiname ein: ");
    		scanf("%s", &output);
    
    		printf("> ------------------------------------------------------------------------------");
    
    		// Speicher allokieren mit dem Pointer pLIST
    		cLIST *pLIST = (cLIST*) malloc(sizeof(cLIST)*nums); 
    
    		// Einzeldateinamen einlesen
    		i=0;
    		do {
    			printf("> Dateiname [Nr.%d]: ", i+1);
    			scanf("%s", pLIST[i].filename);
    			i = i + 1;
    		} while (i < nums);
    
    		// Speicher allokieren
    		printf("> ------------------------------------------------------------------------------");
    		printf("> Allokiere den Speicher...\n");
    
    		ydim = getmaxFileLength(pLIST, nums);
    
    		double **dataBag = (double**) malloc(sizeof(double*) * ydim);
    		for (i = 0; i < ydim; ++i) {
    			dataBag[i] = (double*) malloc(sizeof(double) * xdim);
    		}
    
    		i=0;
    		do {
    			printf("> Scanne %d. Datei: %s\n", i+1, pLIST[i].filename);
    
    			fPtr = fopen(pLIST[i].filename, "r");
    			if (fPtr != NULL) {
    				// Spaltenindex zurücksetzen
    				j=0;
    				while (!feof(fPtr)) {
    					// Textzeile auslesen
    					fgets(string, max, fPtr);
    					RetVal = parse(string, name, &value, unit);
    					if (RetVal == 1) {
    						// Daten ins Feld speichern
    						dataBag[i][j] = value;
    						j = j + 1;
    					} else {
    						dataBag[i][j] = 0;
    					}
    				}
    				fclose(fPtr);
    			} else {
    				printf("> Die Datei: %s konnte nicht ge%cffnet werden. Weiter...\n", pLIST[i].filename, 148);
    			} 
    			i=i+1;
    		} while (i < nums);
    
    		printf("> ------------------------------------------------------------------------------");
    		printf("> Schreibe Werte in die Datei...\n");
    		fPtr = fopen(output, "w");
    		if (fPtr != NULL) {
    			for (i=0; i<nums; i=i+1) {
    				for (j=0; j<ydim-1; j=j+1) {
    					fprintf(fPtr, "%lf\t", dataBag[i][j]);
    				}
    				// Erzeuge Zeilenumbruch
    				fprintf(fPtr, "\n");
    			}
    			fclose(fPtr);
    			printf("> Schreibvorgang erfolgreich beendet.\n");
    		} else {
    			printf("> Die Ausgabedatei konnte nicht zum Schreiben ge%cffnet werden.\n", 148);
    		}
    
    		printf("> ------------------------------------------------------------------------------");
    		printf("\n> Programm beendet.");
    
    	} else {
    		printf("> Das Programm wurde beendet.\n");
    	}	
    }
    


  • W2K2005 schrieb:

    Ich schicke mal das ganze Programm.
    In meiner Eingabedatei steht beispielsweise folgender Text:

    Tja, mit diesen Beispieldaten läufts bei mir.

    Ich glaube eigentlich nicht, dass ich das Feld sprenge

    Leider sind wir aber nicht in der Kirche.

    Ich sags auch gern nochmal:

    MFK schrieb:

    Prüf mal den Wert des Zeigers vor fgets, zwischen fgets und parse, und nach parse.



  • Du hast die Dimensionen von dataBag durcheinandergebracht.

    ydim = getmaxFileLength(pLIST, nums); // ydim = maximale anzahl der zeilen pro file         
            double **dataBag = (double**) malloc(sizeof(double*) * ydim);  // zeilen        
            for (i = 0; i < ydim; ++i) {
                dataBag[i] = (double*) malloc(sizeof(double) * xdim);   // sollte Anzahl der files sein ist aber null ( wird mit 0 initialisiert aber nie geändert )
            }
    

    Weiter unten

    if (RetVal == 1) {
                            // Daten ins Feld speichern
                            // dataBag[i][j] = value; // falsch i = File index, j = Zeilenindex
                            dataBag[j][i] = value; // damit es zusammen passet
    


  • Hi,

    also die Indizes sind nach meiner Meinung richtig - denn ich möchte dass die Werte aus EINER DATEI in einer Zeile in DataBag stehen. Werte aus einzelnen Dateien stehen also jeweils in einer Spalte untereinander!

    Allerdings hattest Du mit xdim recht.

    Der Witz ist, dass das Program gut funktioniert, solange nur eine Datei eingelesen wird - sobald es zwei sind (mit mehr als 15 Zeilen), entsteht ein Ausnahmefehler, in dem Moment, wenn value in DataBag geschrieben werden soll.
    Hat das vielleicht etwas mit der Größe des Feldes zu tun? Meine Datei hat 32 Zeilen.

    32-Zeilen x 2 Dateien x sizeof(double) ????



  • Sag einmal liest du meine Postings überhaupt ?
    Mich interessiert überhaupt nicht ob du die Werte einer Datei in einer Zeile oder einer Spalte speichern willst. Ich habe nur festgestellt das Zeilen- und Spaltenanzahl beim Schreiben und Anlegen nicht das gleiche ist.
    Ausserdem habe ich festgestellt dass einer der Werte ( Zeilen oder Spalten was auch immer 0 ist ).
    Dass dein Programm bei nur einer Datei richtig läuft sagt überhaupt nichts.
    Das Verhalten deines Programmes ist undefiniert. Dein Rechner könnte auch explodieren.
    Kurt



  • w2k2005, an deiner stelle wuerde ich ueberlegen, das programm nochmal von vorn zu schreiben.


Anmelden zum Antworten