Promillerechner CMD Problem



  • Guten Abend,

    ich habe folgendes Problem mit meinem kleinen "Promillerechner"(geschrieben in C und nur stdio.h und stdlib.h verwendet):
    In der IDE läuft er einwandfrei, in einem bereits geöffneten CMD-Fenster läuft er auch einwandfrei. Sobald ich ihn aber "per Hand" starte und sich ein neues CMD-Fenster öffnet gibt er mir am Ende ein falsches Ergebnis aus. Jemand eine Idee woran es liegen könnte? Ich möchte euch an dieser stelle erstmal meinen Code ersparen :D.

    Mfg,
    koelbche


  • Mod

    koelbche schrieb:

    Jemand eine Idee woran es liegen könnte?

    Ja, hier! Ich weiß es! Die Antwort ist: Du hast irgendwo was falsch gemacht.

    Ich möchte euch an dieser stelle erstmal meinen Code ersparen :D.

    Du hast also ein nicht näher beschriebenes Problem mit einem nicht näher beschriebenem Programm. Hast du da eine andere Antwort erwartet?



  • Eigentlich nicht wenn ich meine grandiose Themen Eröffnung so überfliege... 😃 Wie gesagt es handelt sich um einen "Promillerechner", ohnen grossen Grund geschrieben, einfach um die C Kenntnisse für das neue Semester wieder aufzufrischen. Das Problem ist, das Programm läuft in der IDE (Dev-C++) einwandfrei, aus der CMD gestartet läuft es auch einwandfrei, allerdings wenn es startet, und sich ein eigenes CMD-Fenster öffnet gibt er am Ende einen falschen/fehlerhaften Promillewert aus. Ich weiß nicht ob es sich um einen Programmfehler handelt oder direkt mit Windows zu tun hat, deswegen hoffe ich ist die Frage hier richtig aufgehoben. Zum Programmablauf, erst wird der Benutzer auf gefordert seine pers. angaben einzugeben (Funktion: reduktionsfaktor), danach wird der red_fak ausgerechnet. Danach soll die Menge an zu sich genommenem Alkohol ausgerechnet werden (Funktion alkoholmasse). Danach wird der eigentliche Promillewert berechnet (Funktion: promille). Als letztes wird der Promillewert ausgegeben und eine kleine .txt erstellt (Funktion: printfunction). Hier ist dann mal der Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    void reduktionsfaktor(double feld[]);
    double promille(double, double);
    double alkoholmasse(void);
    void printffunction(double feld[]);
    
    int main(void)																								/*buffer[0] = alter */
    {																											/*buffer[1] = groesse */
    	setbuf(stdout,NULL);																					/*buffer[2] = gewicht */
    																											/*buffer[3] = g */	
    	printf("**********************************\n");															/*buffer[4] = alkmasse */
    	printf("******** Promillerechner *********\tby Koelbche\n");											/*buffer[5] = redfak */
    	printf("**********************************\n");															/*buffer[6] = promille */
    	printf("\nDieses Tool dient dazu den maximal erreichbaren Promillewert auszurechnen!");
    	printf("\nAlle Angaben sind ohne Gewaehr und dienen nur als Ungefaehrwert!");
    	printf("\nUm die Getraenkeeingabe zu beenden, beide Fragen mit 0 beantworten!\n\n");
    
    	double buffer[6];
    
    	reduktionsfaktor(buffer);
    	buffer[4] = alkoholmasse(); // alkoholmasse wird berechnet und eingelesen
    
    	buffer[6] = promille(buffer[4],buffer[5]); //eigentlicher promillewert
    
    	printfunction(buffer);
    
    	printf("\n");
    	system("PAUSE");
    
    	return 0;
    }
    
    void reduktionsfaktor(double buffer[])
    {
    	int g;
    	double  gewicht, groesse, alter;
    	double redfak = 0, gkw = 0;
    
    	do
    	{
    
    	printf("Bitte geben Sie Ihr Alter an: ");
    	scanf("%lf", &alter);
    		if(alter<=0)
    		{
    			printf("Ungueltige Altersangabe!\n");
    		}
    	}while(alter<=0);
    
    	do
    	{
    	printf("Nun Ihre Groesse in cm : ");
    	scanf("%lf", &groesse);
    		if(groesse<=0)
    		{
    			printf("Ungueltige Groessenangabe!\n");
    		}
    	}while(groesse <=0);
    
    	do
    	{
    	printf("Bitte noch Ihr Gewicht in kg : ");
    	scanf("%lf", &gewicht);
    		if(gewicht<=0)
    			{
    				printf("Ungueltige Gewichtsangabe!\n");
    			}
    	}while(gewicht <=0);
    
    	do
    	{
    	printf("Als letztes Ihr Geschlecht: \n<1> Maennlich \n<2> Weiblich\n");
    	scanf("%d",&g);
    
    	switch(g)
    	{
    		case 1: gkw = 2.447-0.09516*alter+0.1704*groesse+0.3362*gewicht;
    		break;
    		case 2: gkw = -2.097+0.1069*groesse+0.2466*gewicht;
    		break;
    		default: printf("Ungueltige Geschlechtsangabe\n");
    		break;
    
    	}
    	}while(g<1 || g>2);
    
    	redfak = ((1.055*gkw)/(0.8*gewicht))*gewicht;
    
     	buffer[0] = alter;
    	buffer[1] = groesse;
    	buffer[2] = gewicht;
    	buffer[3] = g;
    	buffer[5] = redfak;
    
    }
    
    double alkoholmasse(void)
    {
    	double * alkoholgehalt;
    	double * menge;
    	double * alkoholmasse;
    	double alkoholmasseges = 0;
    	const double dichtealk = 0.8;
    	int i = 0;
    	int k = 0;
    	int bed = 1;
    
    	alkoholgehalt = (double *) malloc(sizeof(double));
    	menge = (double *) malloc(sizeof(double));
    	alkoholmasse = (double *)malloc(sizeof(double));
    
    	while(bed)
    	{
    		do
    		{
    		printf("Bitte geben Sie die Menge (ml) Ihres %d. Drinks an: ", i+1);
    		scanf("%lf", &menge[i]);
    		if(menge[i]<0)
    		{
    			printf("Ungueltige Eingabe!\n");
    		}
    		}while(menge[i]<0);
    
    		menge = (double *)realloc(menge, (i+2)*sizeof(double));
    
    		do
    		{
    		printf("Bitte geben Sie nun den Alkoholgehalt des Drinks an: ");
    		scanf("%lf", &alkoholgehalt[i]);
    		if(alkoholgehalt[i]<0)
    		{
    			printf("Ungueltige Eingabe!\n");
    		}
    		}while(alkoholgehalt[i]<0);
    		alkoholgehalt = (double *)realloc(alkoholgehalt, (i+2)*sizeof(double));
    
    		alkoholmasse = (double *)realloc(alkoholmasse, (i+2)*sizeof(double));
    		if(menge[i]==0 || alkoholgehalt[i] == 0)
    		{
    			bed = 0;
    		}
    
    	i++;
    	}
    
    	for(k=0;k<=i;k++)
    	{
    		alkoholmasse[k] = menge[k]*(alkoholgehalt[k]/100)*dichtealk;
    		alkoholmasseges = alkoholmasseges + alkoholmasse[k];
    	}
    
    	free(menge);
    	free(alkoholgehalt);
    	free(alkoholmasse);
    
    	//printf("\nAlkoholmasseges: %lf!",alkoholmasseges);
    
    	return(alkoholmasseges);
    
    }
    
    double promille(double alkoholmasse, double redfak)
    {
    	double pro = 0;
    
    	pro = alkoholmasse/redfak;
    
    	//printf("\nPROMILLE: %lf",pro);
    
    	return (pro);
    }
    
    void printfunction(double buffer[])
    {
    	FILE * data_exp;
    	time_t current_time;
    	char * c_time_string;
    	double a,h,m,geschlecht,alkmasse,redfak,pro_wert;
    	a = buffer[0];
    	h = buffer[1];
    	m = buffer[2];
    	geschlecht = buffer[3];
    	alkmasse =  buffer[4];
    	redfak = buffer[5];
    	pro_wert = buffer[6];
    
    	current_time = time(NULL);
    	c_time_string = ctime(&current_time);
    
    	printf("\nIhr max. Promillewert betrug: %.1lf", pro_wert);
    	data_exp = fopen("Promillerechner_Auswertung.txt","a+");
    	fprintf(data_exp,"Eintrag vom: %s", c_time_string);
    	fprintf(data_exp,"Ihre Angaben:\t");
    	fprintf(data_exp,"Geschlecht: ");
    		if(geschlecht==1)
    		{
    			fprintf(data_exp,"maennlich\n");
    		}
    		if(geschlecht==2)
    		{
    			fprintf(data_exp,"weiblich\n");
    		}
    	fprintf(data_exp,"\t\tAlter: %.0lf\n", a); 
    	fprintf(data_exp,"\t\tGroesse: %.1lf\n", h);
    	fprintf(data_exp,"\t\tGewicht: %.1lf\n", m);
    	fprintf(data_exp,"Promillewert: %.2lf\n", pro_wert);
    	fprintf(data_exp,"*********************************\n");
    
    	fclose(data_exp);
    }
    

    Die printfunction schreibt alles richtig in die .txt (alter, groesse, etc.). Nur der am Ende ausgegebene Promillewert (pro_wert) wird fehlerhaft ausgegeben und in die .txt geschrieben. Ich hoffe jemand kann mir helfen 🙂

    Mfg
    koelbche



  • Danke, aber hat sich erledigt, man sollte so dumme Fehler wie system("PAUSE"); halt nicht machen -.-#.


  • Mod

    Du greifst fröhlich auf nicht initialisierten Speicher zu. Guck dir mal deine Werte für i und k um Zeile 151 herum an. Es ist eigentlich ein Wunder, dass da überhaupt jemals ein richtiges Ergebnis kommt. Bei mir kommen die putzigsten Ergebnisse (negative Promille 😃 ). Warum die Art und Weise der Ausführung hier einen Effekt hat, ist ein Rätsel, aber ich hinterfrage undefiniertes Verhalten mal nicht weiter. Jedenfalls ist das schlichtweg falsch und du hast bloß das Pech, dass es manchmal funktioniert hat und du daher den Fehler nicht gesehen hast.

    Ein paar Stilhinweise:

    Lass das Gecaste von malloc-Rückgaben. Ist das hier C++?

    Aktiviere Compilerwarnungen. Hier direkt gefunden: Schreibfehler printffunction. Unbenutzte Variablen alkmasse, redfak.

    Ein paar Buchstaben oder Formatierungen würden dein Programm sehr viel lesbarer machen. alkoholmasseges, dichtealk, g, redfak, und viele andere mehr. Warum nicht alkoholmasse_gesamt, alkohol_dichte, geschlecht, reduktionsfaktor oder etwas ähnliches? Derzeit ist dein Programm für jeden, der nicht du bist, nur sehr schwer verständlich. Das gleiche wird dir passieren, wenn du das Programm in ein paar Tagen nochmal anguckst, du wirst nichts mehr verstehen.

    Das Programm ist natürlich insgesamt ziemlich anfängerhaft geschrieben und von structs hast du wohl noch nie gehört, aber das kann man dir wohl kaum zum Vorwurf machen 😉 . Nur so als Hinweis, dass da prinzipiell noch viel Verbesserungspotential besteht.



  • Ja, also mit dem Codedesign muss ich dir recht geben, das ist wirklich nicht gut, ums mal milde auszudrücken. Danke auch für die Tipps und den Schreibfehler-Hinweis 🙂 Allerdings wieso sollte bei Zeile 151 etwas nicht initialisiert sein? i und k werden doch schon bei der Deklaration mit = 0 initialisiert?


  • Mod

    koelbche schrieb:

    Ja, also mit dem Codedesign muss ich dir recht geben, das ist wirklich nicht gut, ums mal milde auszudrücken. Danke auch für die Tipps und den Schreibfehler-Hinweis 🙂 Allerdings wieso sollte bei Zeile 151 etwas nicht initialisiert sein? i und k werden doch schon bei der Deklaration mit = 0 initialisiert?

    i und k sind schon initialisiert. Ich meine das, was du mit ihnen machst. Du greifst fröhlich hinter den initialisierten Bereich deiner Felder zu! Daher die Unsinnsergebnisse!



  • koelbche schrieb:

    double buffer[6];
     
         .....
       
        buffer[6] = promille(buffer[4],buffer[5]); //eigentlicher promillewert
    

    Nur nochmal zur Erinnerung:
    double buffer[6]; erzeugt ein Array mit 6 Elementen. Die werden mit 0, 1, 2, 3, 4, 5 indiziert.

    Das Element mit dem Index 6 gibt es also gar nicht.



  • Danke DirkB, dass ist ein massiver Bock 😮. Ist mir so leider nicht aufgefallen.



  • Neben dem schon Gesagten:

    Ich hätte da kein Array von double namens buffer genommen, sondern eine passende struct erstellt. (Hätte dir auch das Problem mit dem Index erspart und ist lesbarer.)

    In double alkoholmasse(void) hätte ich mir das ständige allokieren von Speicher gespart. Du möchtest im Endeffekt doch nur alkoholmasseges und das lässt sich in jedem Schleifendurchlauf aktualisieren ohne den Verlauf mitzuschleppen, den du kurz drauf eh wieder löschst.



  • Vielen Danke schon mal für die zahlreichen Tipps. 🙂
    Hab den Quelltext jetzt mal aktualisiert und mich versucht an eure Hinweise zu halten. Hier das Ergebnis 😃 :

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    struct daten
    {
    	double alter;  
    	double groesse;
    	double gewicht;
    	int geschlecht;
    	double alkohol_masse_ges;
    	double red_fak;
    	double promille_wert;
    };
    
    void reduktionsfaktor(struct daten *red_fak_data);
    double promille(double, double);
    double alkohol_masse(void);
    void printfunction(struct daten *data_print);
    
    int main(void)																								
    {																											
    	setbuf(stdout,NULL);																								
    
    	printf("**********************************\n");															
    	printf("******** Promillerechner *********\tby Koelbche\n");											
    	printf("**********************************\n");															
    	printf("\nDieses Tool dient dazu den maximal erreichbaren Promillewert auszurechnen!");
    	printf("\nAlle Angaben sind ohne Gewaehr und dienen nur als Ungefaehrwert!");
    	printf("\nUm die Getraenkeeingabe zu beenden, beide Fragen mit 0 beantworten!\n\n");
    
     	struct daten data;
    
    	reduktionsfaktor(&data); 																			
    	data.alkohol_masse_ges = alkohol_masse(); 															
    	data.promille_wert = promille(data.alkohol_masse_ges,data.red_fak); 								
    	printfunction(&data); 																				
    
    	return 0;
    }
    
    void reduktionsfaktor(struct daten *red_fak_data)
    {
    
    	double gkw = 0;
    
    	do
    	{
    
    	printf("Bitte geben Sie Ihr Alter an: ");
    	scanf("%lf", &red_fak_data->alter);
    		if(red_fak_data->alter<=0)
    		{
    			printf("Ungueltige Altersangabe!\n");
    		}
    	}while(red_fak_data->alter<=0);
    
    	do
    	{
    	printf("Nun Ihre Groesse in cm : ");
    	scanf("%lf", &red_fak_data->groesse);
    		if(red_fak_data->groesse<=0)
    		{
    			printf("Ungueltige Groessenangabe!\n");
    		}
    	}while(red_fak_data->groesse <=0);
    
    	do
    	{
    	printf("Bitte noch Ihr Gewicht in kg : ");
    	scanf("%lf", &red_fak_data->gewicht);
    		if(red_fak_data->gewicht<=0)
    		{
    			printf("Ungueltige Gewichtsangabe!\n");
    		}
    	}while(red_fak_data->gewicht <=0);
    
    	do
    	{
    	printf("Als letztes Ihr Geschlecht: \n<1> Maennlich \n<2> Weiblich\n");
    	scanf("%d",&red_fak_data->geschlecht);
    
    		switch(red_fak_data->geschlecht)
    		{
    			case 1: gkw = 2.447-0.09516*red_fak_data->alter+0.1704*red_fak_data->groesse+0.3362*red_fak_data->gewicht;
    			break;
    			case 2: gkw = -2.097+0.1069*red_fak_data->groesse+0.2466*red_fak_data->gewicht;
    			break;
    			default: printf("Ungueltige Geschlechtsangabe\n");
    			break;
    
    		}
    	}while(red_fak_data->geschlecht<1 || red_fak_data->geschlecht>2);
    
    	red_fak_data->red_fak = ((1.055*gkw)/(0.8*red_fak_data->gewicht))*red_fak_data->gewicht;
    
    }
    
    double alkohol_masse(void)
    {
    	double alkohol_gehalt;
    	double drink_masse;
    	double alkohol_masse;
    	double alkohol_masse_ges = 0;
    	const double dichte_alk = 0.8;
    	int i = 0;
    	int k = 0;
    	int bed = 1;
    
    	while(bed)
    	{
    		do
    		{
    			printf("Bitte geben Sie die Menge (ml) Ihres %d. Drinks an: ", i+1);
    			scanf("%lf", &drink_masse);
    				if(drink_masse<0)
    				{
    					printf("Ungueltige Eingabe!\n");
    				}	
    		}while(drink_masse<0);
    
    		do
    		{
    			printf("Bitte geben Sie nun den Alkoholgehalt in %% des Drinks an: ");
    			scanf("%lf", &alkohol_gehalt);
    
    				if(alkohol_gehalt<0 || alkohol_gehalt > 100)
    				{
    					printf("Ungueltige Eingabe!\n");
    				}
    		}while(alkohol_gehalt<0 || alkohol_gehalt>100 );
    
    			if(drink_masse==0 || alkohol_gehalt== 0)
    			{
    				bed = 0;
    			}
    
    	alkohol_masse = drink_masse*(alkohol_gehalt/100)*dichte_alk;
    	alkohol_masse_ges += alkohol_masse;
    
    	i++;
    	}
    
    	return(alkohol_masse_ges);
    }
    
    double promille(double alkohol_masse_ges, double red_fak)
    {
    	double promille_wert = 0;
    
    	promille_wert = alkohol_masse_ges/red_fak;
    
    	return (promille_wert);
    }
    
    void printfunction(struct daten *data_print)
    {
    	FILE * data_exp;
    	time_t current_time;
    	char * c_time_string;
    
    	current_time = time(NULL);
    	c_time_string = ctime(&current_time);
    
    	printf("\nIhr max. Promillewert betrug: %.2lf", data_print->promille_wert);
    
    	data_exp = fopen("Promillerechner_Auswertung.txt","a+");
    	fprintf(data_exp,"Eintrag vom: %s", c_time_string);
    	fprintf(data_exp,"Ihre Angaben:\t");
    	fprintf(data_exp,"Geschlecht: ");
    
    		if(data_print->geschlecht==1)
    		{
    			fprintf(data_exp,"maennlich\n");
    		}
    
    		if(data_print->geschlecht==2)
    		{
    			fprintf(data_exp,"weiblich\n");
    		}
    
    	fprintf(data_exp,"\t\tAlter: %.0lf\n", data_print->alter); 
    	fprintf(data_exp,"\t\tGroesse: %.1lf\n", data_print->groesse);
    	fprintf(data_exp,"\t\tGewicht: %.1lf\n", data_print->gewicht);
    	fprintf(data_exp,"max. Promillewert: %.2lf\n", data_print->promille_wert);
    	fprintf(data_exp,"*********************************\n");
    
    	fclose(data_exp);
    }
    


  • - die Funktionen sind zu lang
    - unnötig C99
    - keine Datei/Eingabeprüfungen
    - == Vergleiche bei Fließkommazahlen


Log in to reply