Übergabe von 20 Variablen an eine Funktion
-
player4245 schrieb:
Weiss ja nicht genau wie das Programm aussieht, aber wie wärs mit nem 2-Dimensionalen Array?
wieso bekommen wir eigentlich keinen code zu gesicht? das ganze gerate find ich inho doof. aber meine glaskugel sagt mir bei 20 argumenten das die zwar alle zusammengehören aber nicht zwingend in der function verwendet werden. also wird ein pointer auf ein stru ct übergeben und fertig.
-
player4245 schrieb:
Weiss ja nicht genau wie das Programm aussieht, aber wie wärs mit nem 2-Dimensionalen Array?
Hmhm, gute Idee ... Das lasse ich mir mal durch den Kopf gehen...
-
Je nach Datenstruktur eignet sich auch ne Liste. Oder ein Baum.
-
In über 99% aller hier gesehenen Fälle ließe sich das mit einer Zeile ala
fread ( my_struct_pointer, sizeof ( *my_struct_pointer ), N, fp );
erledigen.
Da sich die Leuts aber meistens ihre Daten gern in Klartext ansehen, wird dafür mal eben eine Parameterorgie gestartet.
-
Ok, selber fummeln hat nix gebracht.
Also hier gibts Code:#define NREACTIONS 41 FILE *pFile; /* Datei-Pointer */ int readFileSuccess = 0; /* richtig ausgelesen? 0 = nein, 1 = ja */ int output = 0; /* Aktiviert die Bildschirmausgabe ALLE ausgelesen Werte für ALLE Reatkionen */ int line = 0; /* Zeilennummer in der Datei */ char *pLineToken[1000]; /* Teile einer Zeile = Zelle */ char reactionChar[] = {"#1"}; /* Suchkriterium für die Reaktiosnummer */ char c[10000]; /* Char-Array, in dem der Dateiinhalt ZEILENWEISE abgelegt werden */ int reactionNumberFile = 0; /* Reaktionsnummer in REACTDAT - Zero-Offset! */ int relevantLine; /* Wird benötigt um anhand von diesem Wert zur relevanten Zeile zu gelangen */ double C[NREACTIONS][10]; /* 10 Koeffizienten */ double P[NREACTIONS][10]; /* 10 Exponenten */ double A[NREACTIONS]; /* Offset */ char model[NREACTIONS][100]; /* Model: NREACTIONSx100 Zeichen */ double modelOrder[NREACTIONS]; /* Reaktions-Ordnung */ double polynomType[NREACTIONS]; /* Polynom-Typ */ double T_min[NREACTIONS], T_max[NREACTIONS]; /* Valider Temperaturbereich für die Polynome */ double pO2_min[NREACTIONS], pO2_max[NREACTIONS]; /* Valider Sauerstoffpartialdruckbereich für die Polynome */ double dt_min[NREACTIONS], dt_max[NREACTIONS]; /* Valider Aufheizgeschwindigkeitsbereich für die Polynome */ double medium[NREACTIONS]; /* Reaktionsumgebung */ double diam_min[NREACTIONS], diam_max[NREACTIONS]; /* Valider Durchmesserbereich für die Polynome */ double betaT0[NREACTIONS]; /* Referenzwert für die Aufheizgeschwindigkeit */ double pO20[NREACTIONS]; /* Referenzwert für den Sauerstoffpartialdruck */ double T0[NREACTIONS]; /* Bezugstemperatur */ char literatureSource[NREACTIONS][100]; /* Literaturquelle: 100x100 Zeichen */ pFile = fopen("reacdat.csv", "r"); if(pFile==NULL) { Message0("Fehler: Kann die Datei nicht öffnen! Ist die im Simulationsverzeichnis vorhanden?\n"); /* fclose(pFile); DON'T PASS A NULL POINTER TO fclose !! */ } else { Message0("Datei erfolgreich geöffnet.\n"); readFileSuccess = 1; while(fgets(c, 10000, pFile)!=NULL) { /* Schleife durch die Zeile, bis zum NULL-Pointer */ /* Das Zeilenende wird als NULL-Pointer (Error) gewertet */ line++; strToken(c,";",pLineToken); /* Aufspalten der Zeile in Token */ /* Ab hier liegt die Zeile aufgespaltet in pLineToken vor */ /* Analysieren auf den Eintrag 'Reaktionsnummer' an erster Stelle (pLineToken[0])*/ sprintf(reactionChar,"%s%d","#",reactionNumberFile+1); /* Schreibt den zu suchenden String (z.B. "#1") in den char reactionChar */ /* Message0("reactionChar: %s\n",reactionChar);*/ if (strcmp(pLineToken[0],reactionChar) == 0){ /* Vergleicht den ersten Spalteneintrag mit dem reactionChar auf der Suche nach der Reaktionsnummer (z.B. #1) */ if (output == 1){ Message0("Reaktion %s in Zeile %d gefunden!\n",reactionChar,line); } if (reactionNumberFile != 24){ reactionNumberFile++; /* Reaktionsnummer wird um 1 erhöht - um die nächste Reaktion finden zu können */ /* ACHTUNG: Das bedeutet auch, dass die AKTUELLE Reaktionsnummer (reactionNumberFile-1) ist!!! */ } else{ /* nach der Reaktionsnummer 25 wird in der Tabelle auf 33 gesprungen */ reactionNumberFile = 32; } /* Auf der Suche nach den reaktionskinetischen Details wird frühestens 5 Zeilen später ein Eintrag gefunden (vgl. Tabelle) */ relevantLine = line + 5; /* In Line 6 suchen! */ } if (line == relevantLine){ /* zu suchende Zeile gefunden: hier beginnen die Daten für die Reaktionskinetik */ if(strcmp(pLineToken[0],"1") == 0){ /* Reaktionspolynom ist aktiv */ /* Reaktionsmodell als char auslesen */ strncpy(model[reactionNumberFile-1],pLineToken[1],100); /* Reaktionsordnung als double auslesen */ sscanf(pLineToken[2],"%lf",&modelOrder[reactionNumberFile-1]); /* Polynom-Typ als double auslesen */ sscanf(pLineToken[3],"%lf",&polynomType[reactionNumberFile-1]); /* Polynom-Koeffizienten als double auslesen */ sscanf(pLineToken[4],"%lf",&C[reactionNumberFile-1][0]); sscanf(pLineToken[6],"%lf",&C[reactionNumberFile-1][1]); sscanf(pLineToken[8],"%lf",&C[reactionNumberFile-1][2]); sscanf(pLineToken[10],"%lf",&C[reactionNumberFile-1][3]); sscanf(pLineToken[12],"%lf",&C[reactionNumberFile-1][4]); sscanf(pLineToken[14],"%lf",&C[reactionNumberFile-1][5]); sscanf(pLineToken[16],"%lf",&C[reactionNumberFile-1][6]); sscanf(pLineToken[18],"%lf",&C[reactionNumberFile-1][7]); sscanf(pLineToken[20],"%lf",&C[reactionNumberFile-1][8]); sscanf(pLineToken[22],"%lf",&C[reactionNumberFile-1][9]); /* Polynom-Exponenten als double auslesen */ sscanf(pLineToken[5],"%lf",&P[reactionNumberFile-1][0]); sscanf(pLineToken[7],"%lf",&P[reactionNumberFile-1][1]); sscanf(pLineToken[9],"%lf",&P[reactionNumberFile-1][2]); sscanf(pLineToken[11],"%lf",&P[reactionNumberFile-1][3]); sscanf(pLineToken[13],"%lf",&P[reactionNumberFile-1][4]); sscanf(pLineToken[15],"%lf",&P[reactionNumberFile-1][5]); sscanf(pLineToken[17],"%lf",&P[reactionNumberFile-1][6]); sscanf(pLineToken[19],"%lf",&P[reactionNumberFile-1][7]); sscanf(pLineToken[21],"%lf",&P[reactionNumberFile-1][8]); sscanf(pLineToken[23],"%lf",&P[reactionNumberFile-1][9]); /* Offset als double auslesen */ sscanf(pLineToken[24],"%lf",&A[reactionNumberFile-1]); /* Referenzwerte als double auslesen */ sscanf(pLineToken[34],"%lf",&betaT0[reactionNumberFile-1]); /* Bezugsaufheitzgeschwindigkeit */ sscanf(pLineToken[35],"%lf",&pO20[reactionNumberFile-1]); /* Bezugssauertoffpartialdruck */ sscanf(pLineToken[36],"%lf",&T0[reactionNumberFile-1]); /* Bezugstemperatur */ /* Restliche Einträge */ sscanf(pLineToken[25],"%lf",&T_min[reactionNumberFile-1]); /* T_min */ sscanf(pLineToken[26],"%lf",&T_max[reactionNumberFile-1]); /* T_max */ sscanf(pLineToken[27],"%lf",&pO2_min[reactionNumberFile-1]); /* pO2_min */ sscanf(pLineToken[28],"%lf",&pO2_max[reactionNumberFile-1]); /* pO2_max */ sscanf(pLineToken[29],"%lf",&dt_min[reactionNumberFile-1]); /* dt_min */ sscanf(pLineToken[30],"%lf",&dt_max[reactionNumberFile-1]); /* dt_max */ sscanf(pLineToken[31],"%lf",&medium[reactionNumberFile-1]); /* medium */ sscanf(pLineToken[32],"%lf",&diam_min[reactionNumberFile-1]); /* diam_min */ sscanf(pLineToken[33],"%lf",&diam_max[reactionNumberFile-1]); /* diam_max */ sscanf(pLineToken[30],"%lf",&diam_max[reactionNumberFile-1]); /* diam_max */ strncpy(literatureSource[reactionNumberFile-1],pLineToken[37],100); /* Literaturquelle */ } /* Ende: aktives Reaktionspolynom */ else{ /* Reaktionspolynom ist nicht aktiv */ relevantLine++; /* in der nächsten Zeile nach einem aktiven Reaktionspolynom suchen */ } } } Message0("Schließe Datei...\n"); fclose(pFile); }
Der Code durchwühlt eine CSV Datei und belegt die Datenfelder
double C[NREACTIONS][10]; /* 10 Koeffizienten */ double P[NREACTIONS][10]; /* 10 Exponenten */ double A[NREACTIONS]; /* Offset */ char model[NREACTIONS][100]; /* Model: NREACTIONSx100 Zeichen */ double modelOrder[NREACTIONS]; /* Reaktions-Ordnung */ double polynomType[NREACTIONS]; /* Polynom-Typ */ double T_min[NREACTIONS], T_max[NREACTIONS]; /* Valider Temperaturbereich für die Polynome */ double pO2_min[NREACTIONS], pO2_max[NREACTIONS]; /* Valider Sauerstoffpartialdruckbereich für die Polynome */ double dt_min[NREACTIONS], dt_max[NREACTIONS]; /* Valider Aufheizgeschwindigkeitsbereich für die Polynome */ double medium[NREACTIONS]; /* Reaktionsumgebung */ double diam_min[NREACTIONS], diam_max[NREACTIONS]; /* Valider Durchmesserbereich für die Polynome */ double betaT0[NREACTIONS]; /* Referenzwert für die Aufheizgeschwindigkeit */ double pO20[NREACTIONS]; /* Referenzwert für den Sauerstoffpartialdruck */ double T0[NREACTIONS]; /* Bezugstemperatur */ char literatureSource[NREACTIONS][100]; /* Literaturquelle: 100x100 Zeichen */
...
Das würde ich gerne vom restlichen Code trennen.
Wenn ich jetzt eine Funktion schreibe, was muss ich dann in den Funktionsaufruf packen, so dass die Funktion die Variablen dann auch im aufrufenden Codeabschnitt füllt?
Kommen da auch pointer ins Spiel?
-
Das kommt wie immer darauf an. Einige Kriterien sind:
Muss es unbedingt eine CSV Datei sein?
Nein: Datenstrukturen anlegen und den Inhalt mit einer Zeile fread einlesen.Sollen die Variablen global sein?
Ja: Es brauchen keine Parameter übergeben werden, das Einlesen kann in einer Prameterlosen Funktion erfolgen, die globalen Variablen sind in einer Headerdatei deklariert und mittels #include eingebunden.Nein: Die Variablen sind innerhalb einer Funktionen deklariert und werden entweder in einer Parameterliste oder in einer Struktur gekapselt an die Einlesefuktion übergeben.
Für jedes Kriterium gibt es pro und kontra Argumente.
Entscheidend ist was du möchtest, oder was dein Programmmachen soll.
-
Muss es unbedingt eine CSV Datei sein?
Nein: Datenstrukturen anlegen und den Inhalt mit einer Zeile fread einlesen.Ja, es ist eine CSV-Datei.
Sollen die Variablen global sein?
Ja, die Variablen sind das zentrale Element des Programms.
Mit den Variablen wird jede Menge Zeug angestellt.Ja: Es brauchen keine Parameter übergeben werden, das Einlesen kann in einer Prameterlosen Funktion erfolgen, die globalen Variablen sind in einer Headerdatei deklariert und mittels #include eingebunden.
Wohin mit dem Header?
In die Funktion?--------------
Ich stelle mir das jetzt so vor:
#define NREACTIONS 41 /* Definitionen */ double C[NREACTIONS][10]; double P[NREACTIONS][10]; double A[NREACTIONS]; char model[NREACTIONS][100]; /* usw */ void readTheFile(){ /* mach den ganzen sscanf()-Kram */ } void main(){ /* Hauptprogramm */ /* Jetzt gehts los mit Datei-Auslesen */ readTheFile(); /* sind die Variablen jetzt belegt ? */ }
-
Ja, es ist eine CSV-Datei.
Wenn du Einfluß darauf hast und das ändern kannst, könnte es sich lohnen, dies zu ändern (Deine Einlesefunktion mit den ganzen hartkodierten Arraygrößen scheint mir auf wackeligen Beinen zu stehen.) ...
Sonst:
Der Header mit den Variablen wird mit der #include Anweisung in die C Datei(en) eingebunden, wo sie gebraucht werden.
Direkt in die Funktion ist ungünstig, wenn die Variablen auch noch in anderen Funktionen/Dateien gebraucht werden, wovon ich jetzt einfach mal ausgehe.Hier ein Ansatz:
// Datei variable.h #ifndef VARIABLE_H #define VARIABLE_H double C[NREACTIONS][10]; double P[NREACTIONS][10]; double A[NREACTIONS]; char model[NREACTIONS][100]; // .. usw. #endif // VARIABLE_H // Datei read_file.h #ifndef READ_FILE_H #define READ_FILE_H void readTheFile(); #endif // READ_FILE_H // Datei read_file.c #include "variable.h" int readTheFile(){ /* mach den ganzen sscanf()-Kram */ if ( error ) return 1; return 0; } // Datei main.c #include "read_file.h" int main() { if ( readTheFile() ) // Fehlerbehandlung ... return 0; }
-
Big Brother schrieb:
Wenn du Einfluß darauf hast und das ändern kannst, könnte es sich lohnen, dies zu ändern (Deine Einlesefunktion mit den ganzen hartkodierten Arraygrößen scheint mir auf wackeligen Beinen zu stehen.) ...
Nein leider nicht.
Die Daten kommen zwar aus einer OpenOffice/Excel-Tabelle aber die Schnittstelle im Programm sollte schon eine Textdatei sein.Sonst:
Der Header mit den Variablen wird mit der #include Anweisung in die C Datei(en) eingebunden, wo sie gebraucht werden.
Direkt in die Funktion ist ungünstig, wenn die Variablen auch noch in anderen Funktionen/Dateien gebraucht werden, wovon ich jetzt einfach mal ausgehe.Die Datei wird nur 1x eingelesen und die Variablen bleiben dann bestehen.
Ich habe es jetzt so (ähnlich) wie in Deinem Vorschlag umgesetzt und das sieht gut aus. Viele Dank für die Hilfestellung!
-
Wofür sind structs denn da? Du hast eine CSV-Datei mit 20 verschiedenen Spalten/Werten. Also eine Art Daten-Schema.
Demnach stellt sich die Frage nicht.
-
Janjan schrieb:
Je nach Datenstruktur eignet sich auch ne Liste. Oder ein Baum.
Hmm, das versteh ich nicht. Ich hab immer gedacht, dass eine Liste oder ein Baum eine Datenstruktur ist.
-
mngbd schrieb:
Janjan schrieb:
Je nach Datenstruktur eignet sich auch ne Liste. Oder ein Baum.
Hmm, das versteh ich nicht. Ich hab immer gedacht, dass eine Liste oder ein Baum eine Datenstruktur ist.
Damit meinte ich je nach Aufbau der Daten in der Datei.
Bzw. die eingelesenen Daten.