Probleme mit dem C-Programm
-
Hallo C Community ich benötige dringend eure Hilfe,
Ich habe in meinem Studium u.a. das Modul Informatik und dort beschäftigen wir uns derzeit mit den Grundlagen der C-Programmierung. Damit wir Praxis bekommen, können wir dazu Aufagaben lösen und genau zu so einer Aufgabe hätte ich eine Frage:
Es geht um die BMI-Berechnung.
Also ich habe eine Textdatei, in der pro Zeile ein Gewicht- und ein Größen-Wert mit einem Leerzeichen getrennt steht, soweit so gut.
Die Datei bekommen ich zum lesen geöffnet, kann auch auf die Werte zugreifen und den BMI mittels einer Funktion berechnen. Er gibt mir auch alles, wie gewünscht aus.
Nun zu meinem Problem, an dem ich seit Tagen verzweifel. Ich bin durch sämltliche Foren gekrochen und konnte für mich nichts erleuchtendes finden.
Ich muss von diesen berechneten BMI-Werte nun das Minimum, Maximum und den Durchschnitt berechnen. Wenn ich aber jetzt beispielsweise mittels eine Minimums-Funktion auf die Werte zugreifen möchte, dann kommt entweder 0, er zeigt mir den letzten BMI-Wert (der nicht der kleinste) ist an oder gibt mit NAN aus.
Ich vermute, dass ich die BMI werte irgendwie an einen Vekotor übergeben muss, aber das bekomme ich auch nicht wirklich hin. Ich hoffe ihr könntet mir vlt helfen.Hier wäre mein 1.Quellcode dazu (Ich habe noch einen zweiten, aber mit dem bekomme ich nicht mal den BMI berechnet) :
#include <stdio.h> #include <stdlib.h> #define MAX 1000 int main() { FILE*datei; char text[100+1]; int anz=0; float gewicht, groesse, ergebnis, klasse; float minimal; int i=0; char ergebnisklasse; float bmi[1000]={0}; int index=0; datei = fopen("test.dat", "r"); if(datei==NULL) { printf("nicht geoffnet\n"); return 1; } else { fscanf(datei,"%c",text); text[100] = '\0'; while((fscanf(datei,"%f %f",&gewicht,&groesse))==2) { float bmi (float, float); ergebnis=bmi(gewicht,groesse); printf("%f\t%f\t%f\t",gewicht,groesse,ergebnis); anz++; char klassifikation (float); ergebnisklasse=klassifikation(ergebnis); printf("%c\n", ergebnisklasse); } printf("ANZAHL DER MESSWERTE.%i\n",anz); float minimum(float); minimal=minimum(ergebnis); printf("Minimum: %f",minimal); fclose(datei); } } float bmi (float gewicht, float groesse) { float bodymassindex; bodymassindex=(gewicht/((groesse/100)*(groesse/100))); return(bodymassindex); } char klassifikation (float ergebnis) { float klasse; if(ergebnis<19) printf("Untergewicht"); if((ergebnis>=19)&&(ergebnis<=24.9)) printf("Normalgewicht"); if((ergebnis>=25)&&(ergebnis<=29.9)) printf("Uebergewicht"); if((ergebnis>=30)&&(ergebnis<=39.9)) printf("Adipositas"); if(ergebnis>=40) printf("mas. Adipositas"); return(klasse); } float minimum (float ergebnis) { float min; if(ergebnis<min) { min=ergebnis; return (min); } }
-
bmi existiert sowohl als Array wie auch als Funktion, sowas macht man nicht.
Du füllst das bmi-Array überhaupt nicht.
Das ist aber wichtig, um anschließend aus allen Elementen des Array das Minimum usw. berechnen zu können.float minimum (float ergebnis) { float min; if(ergebnis<min) { min=ergebnis; return (min); } }
Das ist Unsinn, überleg mal, was hier passiert (nimm einen Debugger).
Schreibe dir für die 3 zu bestimmenden Werte jeweils eine Funktion, die das bmi-Array und dessen Länge übergeben bekommt.
-
Was macht denn der Compiler für Meldungen. Auch Warnungen musst du ernst nehmen.
Wenn du keine bekommst, musst du den Warnlevel höher setzen (wie das geht, hängt vom Compiler ab)#include <stdio.h> #include <stdlib.h> #define MAX 1000 // Warum definierst du MAX, wenn du es nie benutzt? int main() { FILE*datei; char text[100+1]; int anz=0; float gewicht, groesse, ergebnis, klasse; float minimal; int i=0; char ergebnisklasse; float bmi[1000]={0}; int index=0; datei = fopen("test.dat", "r"); if(datei==NULL) { printf("nicht geoffnet\n"); return 1; } else { fscanf(datei,"%c",text); // Warum wird hier Was eingelesen? text[100] = '\0'; while((fscanf(datei,"%f %f",&gewicht,&groesse))==2) { float bmi (float, float); // Diese Deklaration sollte vor main stehen ergebnis=bmi(gewicht,groesse); printf("%f\t%f\t%f\t",gewicht,groesse,ergebnis); anz++; char klassifikation (float); // Diese Deklaration sollte vor main stehen ergebnisklasse=klassifikation(ergebnis); // klar, hier hast du immer das letzte ergebnis printf("%c\n", ergebnisklasse); // Welchen Wert soll ergebnisklasse haben? Einen Zahlenwert oder ein Zeichen? passt das zu %c ? } printf("ANZAHL DER MESSWERTE.%i\n",anz); float minimum(float); // Diese Deklaration sollte vor main stehen minimal=minimum(ergebnis); printf("Minimum: %f",minimal); fclose(datei); } } float bmi (float gewicht, float groesse) { float bodymassindex; bodymassindex=(gewicht/((groesse/100)*(groesse/100))); return(bodymassindex); } char klassifikation (float ergebnis) //ein char als Rückgabewert { float klasse; if(ergebnis<19) printf("Untergewicht"); if((ergebnis>=19)&&(ergebnis<=24.9)) printf("Normalgewicht"); if((ergebnis>=25)&&(ergebnis<=29.9)) printf("Uebergewicht"); if((ergebnis>=30)&&(ergebnis<=39.9)) printf("Adipositas"); if(ergebnis>=40) printf("mas. Adipositas"); return(klasse); // hier gibst du ein float zurück, derr noch keinen Wert bekommen hat // Passt das zum Rückgabewert aus der Deklartion? } float minimum (float ergebnis) { float min; // Welchen Wert hat min hier? Das ist eine lokale Variable if(ergebnis<min) { min=ergebnis; return (min); } // hier hört min auf zu existieren, ergebnis auch }
Lokale Variablen heißen lokal, weil sie lokal sind.
-
Wutz schrieb:
bmi existiert sowohl als Array wie auch als Funktion, sowas macht man nicht.
Du füllst das bmi-Array überhaupt nicht.
Das ist aber wichtig, um anschließend aus allen Elementen des Array das Minimum usw. berechnen zu können.Da stellt sich mir ja jetzt die Frage, wie fülle ich das Array richtig. Das muss ich ja prinzipiell auch über eine Funktion (Berechnung des BMI's aus Gewicht und Größe)und Schleife machen, oder?
würde ich mir jetzt so vorstellen, ist aber bestimmt wieder völliger Quatsch:
void bodymassindex(float gewicht,float groesse, float*bmi) { int i; float loesung; for (i=0;i<MAX;i++) { loesung=(gewicht/(groesse/100)*(groesse/100)); bmi[i]=loesung; } }
Wutz schrieb:
float minimum (float ergebnis) { float min; if(ergebnis<min) { min=ergebnis; return (min); } }
Das ist Unsinn, überleg mal, was hier passiert (nimm einen Debugger).
Schreibe dir für die 3 zu bestimmenden Werte jeweils eine Funktion, die das bmi-Array und dessen Länge übergeben bekommt.Prinzipiell stelle ich mir vor, dass meine Minimums-Funktion das Minimum mittels eines Vergleiches ermittelt. Also ich eine Variable für das Minimum habe und dieser Wert immer mit dem letzten errechneten BMI-Wert verglichen wird. Wenn dieser kleiner ist, als der von der Variablen, soll er gespeichert werden und mit dem nächsten verglichen. Nur dafür brauche ich anscheinend den Vektor, der bei mir leer ist und deshalbt macht der ausdruck 'ergebnis<min' keinen Sinn oder?
DirkB schrieb:
while((fscanf(datei,"%f %f",&gewicht,&groesse))==2) { float bmi (float, float); // Diese Deklaration sollte vor main stehen ergebnis=bmi(gewicht,groesse); printf("ANZAHL DER MESSWERTE.%i\n",anz); }
Warum sollte das, jetzt vetreten für alle, die ähnlich sind, vor main stehen? Eigentlich ist es doch mein Funktionsaufruf und muss dieser nicht in der Funktion erfolgen?
-
Fussel94 schrieb:
Da stellt sich mir ja jetzt die Frage, wie fülle ich das Array richtig. Das muss ich ja prinzipiell auch über eine Funktion (Berechnung des BMI's aus Gewicht und Größe)und Schleife machen, oder?
Das beste ist, du füllst da Array dann, wenn du die Daten dafür hast.
Und das ist direkt in der Schleife, in der du die Daten einliest.Fussel94 schrieb:
würde ich mir jetzt so vorstellen, ist aber bestimmt wieder völliger Quatsch:
Ja, ist es.
Du übergibst Werte für einen BMI (Länge und Masse) und berechnest daraus das ganze Feld.Du kannst noch einen Paramter mit übergeben: Den Index des zu berechnenden Elements.
Aber das ist auch überflüssig, da du das auch als Zuweisung machen kannst.ergebnis=bodymassindex(gewicht,groesse); bmi[index] = ergebnis; index++;
Fussel94 schrieb:
Prinzipiell stelle ich mir vor, dass meine Minimums-Funktion das Minimum mittels eines Vergleiches ermittelt. Also ich eine Variable für das Minimum habe und dieser Wert immer mit dem letzten errechneten BMI-Wert verglichen wird. Wenn dieser kleiner ist, als der von der Variablen, soll er gespeichert werden und mit dem nächsten verglichen. Nur dafür brauche ich anscheinend den Vektor, der bei mir leer ist und deshalbt macht der ausdruck 'ergebnis<min' keinen Sinn oder?
Für den Vergleich brauchst du erstmal zwei Werte. Du hast aber nur einen (das aktuelle Ergebnis)
Du musst deiner Funktion auch das bisherige Minimum mit übergeben.
Da du die Funktion dann aber auch in der Leseschleife aufrufst, brauchst du das Array nicht mehr.Einlesen, Berechnung (evtl. ablegen im Array) und Bestimmung des Minimum kannst du alles in der Einleseschleife machen.
Möchtest du das Minimum erst später bestimmen, musst du das Array und die Anzahl der gültigen Einträge (im Array) an die Funktion mit übergeben.
In der Funktion ist dann die Schleife, die die Werte durchsucht.Fussel94 schrieb:
DirkB schrieb:
float bmi (float, float); // Diese Deklaration sollte vor main stehen ergebnis=bmi(gewicht,groesse); }
Warum sollte das, jetzt vetreten für alle, die ähnlich sind, vor main stehen? Eigentlich ist es doch mein Funktionsaufruf und muss dieser nicht in der Funktion erfolgen?
Die Deklaration dient dazu, dem Compiler mitzuteilen, welche Paramter die Funktion erwartet.
Die Deklaration muss vor dem ersten Aufruf der Funktion gemacht werden.
Dies kann man auch erreichen, indem man die Funktion vorher definiert.Bei
printf, fopen
undfscanf
hast du ja vor deren Aufruf auch keine Deklaration geschrieben.
Die wird nämlich in stdio.h gemacht (und das steht auch vor main)
-
Soo, jetzt habe ich es denke ich mal erfolgreicht geschafft die BMI-Werte in ein Arry zu übergeben. Er zeigt sie mir auch korrekt an.
Das mit der Deklaration vor main leuchtet mir jetzt auch ein.Nun nochmal eine Frage zu dem Minimum.
Funktion:
float minimum (float bodymassindex[], int MAX) { int min=bodymassindex[0], i; for(i=1;i<size;i++) { if(bodymassindex[i]<min) { min=bodymassindex[i]; } }return min; }
Funktionsaufruf im main:
minimal=minimum(bodymassindex[MAX],index); printf("Minimum: %f",minimal);
Du hast ja gesagt, dass ich das Array und die Anzahl der gültigen Elemente in die Funktion übergeben muss.
Wie du wahrscheinlich selber erkennst, bekomme ich einen Fehler.
Ich bin mir zum einen nicht sicher, ob ich das Array in dieser Form an die Funktion übergeben kann und ob ich für die Anzahl 'MAX' oder den 'index' nehmen muss. Der 'index' Wert hat ja theoretisch "gezählt" wie oft der BMI berechnet wurde oder?
-
Habe den ersten Fehler darin gefunden.
Gibt aber jetzt einen zweiten. Er gibt mir den Minimal-Wert glatt aus, also normalerweise müsste da ein Wert in der Art 7.821 stehen, aber er schreibt nur 7.000printf("Minimum: %.2f",minimum(bodymassindex,index));
float minimum (float *bodymassindex, int size) { int min=bodymassindex[0], i; for(i=1;i<size;i++) { if(bodymassindex[i]<min) { min=bodymassindex[i]; } }return min; }
-
Fussel94 schrieb:
Habe den ersten Fehler darin gefunden.
Gibt aber jetzt einen zweiten. Er gibt mir den Minimal-Wert glatt aus, also normalerweise müsste da ein Wert in der Art 7.821 stehen, aber er schreibt nur 7.000Erklär mal, was diese Zeile bedeutet:
int min=bodymassindex[0],i;
-
Na ich würde denke, dass ich damit das Erste Element des Vektor an eine lokale Variable übergebe, die somit meinen Startwert darstellt.
und i ist dann die Laufvariable mit der die Schleife durchlaufen wird, bis der kleinste Wert ermittelt werden konnte. oder??
-
ach mist ich mache ja dann aus meinem bodymassindex[] auch einen int vektor oder?
-
Fussel94 schrieb:
ach mist ich mache ja dann aus meinem bodymassindex[] auch einen int vektor oder?
Nein, hat nix mit vektor zu tun.
int min=bodymassindex[0],i;
wäre höflicher geschrieben
int min=bodymassindex[0]; int i;
Brauchbar wäre
float min=bodymassindex[0]; int i;
-
min ist ein
int
. Also können in min auch nur Ganzzahlen gespeichert werden.
-
Jaa, genau so habe ich es dann abgeändert, als du mir die Frage gestellt hattest :).
Dann hätte ich noch eine Frage. Desweiteren muss ich mit dem Programm bestimmen, wie viele Patieten der jeweiligen BMI-Klasse angehören.
Die Klassen zu den jeweiligen Werten habe ich ja bereits bestimmt:
char klassifikation (float ergebnis) { if(ergebnis<19) printf("Untergewicht"); if((ergebnis>=19)&&(ergebnis<=24.9)) printf("Normalgewicht"); if((ergebnis>=25)&&(ergebnis<=29.9)) printf("Uebergewicht"); if((ergebnis>=30)&&(ergebnis<=39.9)) printf("Adipositas"); if(ergebnis>=40) printf("mas. Adipositas"); return 0; }
und ich hoffe er hat sie hier in ein Array übergeben, ist ja eigentlich ähnlich den BMI-Werten, angezeigt werden sie auch richtig:
ergebnisklasse=klassifikation(ergebnis); k[aindex]=ergebnisklasse; aindex++; printf("%c\n", ergebnisklasse);
Um jetzt die Patietenanzahl für jede Klasse zu bestimmen, würde ich irgendwie in diesem char array eine Zeichenkette (entsprchend der Klassenbezeichnung) suchen lassen und immer wenn er eine gefunden hat, zählen.
Ich habe das ganze erst einmal versucht für die Klasse "Untergewicht" umzusetzen und wie so oft ist da wieder irgendetwas falsch und ich würde jetzt erst einmal vermuten, dass es an der Wertzuweisung der Variablen 'char zeichen1[]={"Untergewicht"}' liegt
Funktion:
int count_klasse(char *k, int size) { int i=0; int z=0; char zeichen1[]={"Untergewicht"}; for(i=0;i<size;i++) { if(k[i]==zeichen1[0]) z++; }return z; }
Wertausgabe in main:
printf("Untergewicht:%i",count_klasse(k,aindex));
-
Hat sich alles erledigt :).
Vielen Dank für die freundliche Hilfe