• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

studentisches c projekt

dom

Newbie
hallo liebe foren mitglieder und frohe weihnachten,
ich habe durch mein studium ein kleines c programm zu erstellen unter linux.
mein problem ist es funktioniert noch nicht so ganz richtig.
daher meine frage falls jmd zeit und lust hat sich den quellcode anzuschauen und mir evtl. tipps zu geben.
ich werde meine betreffende stelle markieren und ein kommentar mit meiner problemschilderung ausführen.
vielen dank für eure hilfe.
mfg dom



Code:
/*kleines_kochbuch.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

main() {

float Vorspeise[7];
float Hauptgericht[7];
float Nachspeise[4];
float Zutaten;


Vorspeise[0]= 2;char string1[]="Tomate(n)";					//2 Tomaten
Vorspeise[1]= 1;char string2[]="Zwiebel(n)";					//1 Zwiebel
Vorspeise[2]= 1;char string3[]="EL Olivenoel";					//El olivenöl
Vorspeise[3]= 1;char string4[]="Zehe(n) Knoblauch";				//1 Zehe Knoblauch
Vorspeise[4]= 5;char string5[]="Gramm Pfeffer";					//5 g Pfeffer
Vorspeise[5]= 5;char string6[]="Gramm Salz";					//5 g Salz
Vorspeise[6]= 2;char string7[]="Scheiben Baguette";				//2 Scheiben Baguette	

Hauptgericht[0]=150;					//150g Kablbsschnitzel
Hauptgericht[1]=1;					//1 Ei
Hauptgericht[2]=60;					//60g Schmalz
Hauptgericht[3]=0.25;					//0,25 Stück Zitrone
Hauptgericht[4]=50;					//50g Mehl
Hauptgericht[5]=50;					//50g Semmelbrösel
Hauptgericht[6]=100;					//100g Kartoffeln

Nachspeise[0]=1;					//1 Ei
Nachspeise[1]=100;					//100g Mehl
Nachspeise[2]=125;					//125 ml Milch
Nachspeise[3]=50;					//50g Marmelade ihrer Wahl

int R;
int P;
int i;
int Z;


printf("\n\t\tKleines Kochbuch\n");
printf("\nZur Auswahl stehen 3 Rezepte :\n\n1.Bruschetta\n2.Kalbschnitzel mit Kartoffel\n3.Pfannkuchen\n");
printf("\nWaehlen Sie die Nummer ihres gewuenschten Rezeptes : ");
scanf("%i",&R);




switch (R) {

case 1:
printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
scanf("%i",&P);
printf("\nSie benoetigen folgende Zutaten für die Vorspeise :\n"); 
for (i=0;i<=6;i++) {
Zutaten=Vorspeise[i]*P;
printf("\n%.2f %s %s",Zutaten,string1,string2);      //## wenn man es so kompiliert schreibt er mir den string1,string2 untereinader,wie bekomme ich die zutaten passend zum float befehl? ich hoffe ihr versteht mich! ##
}
									
break;
case 2:
printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
scanf("%i",&P);
printf("\nSie benoetigen folgende Zutaten für die Hauptspeise :\n");		
for (i=0;i <=6;i++) {
Zutaten=Hauptgericht[i]*P;
printf("\n%.2f",Zutaten);
}

break; 
case 3:
printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
scanf("%i",&P);
printf("\nSie benoetigen folgende Zutaten für die Nachspeise :\n");								
for (i=0;i<=3;i++) {
Zutaten=Nachspeise[i]*P;
printf("\n%.2f",Zutaten);
}
break;

default:
if (R == 1||2||3) {
printf("\nEs stehen nur 3 Rezepte zur Auswahl bitte nochmal Waehlen!\n");
}
return 0;
break;

} 
printf("\n\tViel Spaß bei der Zubereitung und guten Appettit!\n");
}
 

abgdf

Guru
Hallo,

immerhin läuft es schonmal. ;)

Erstmal ein paar Konventionen:
1. main() sollte int zurückgeben.
2. Normale Variablen sollten kleingeschrieben werden, also:
Code:
float vorspeise[7];
Ob man deutsche Variablennamen verwenden sollte?
3. Variablennamen "string1", usw., sind nicht sehr aussagekräftig.
4. Bitte benutze Einrückungen und auch Leerzeichen. Für die Einrückungen bitte 4 Leerzeichen pro Block. Z.B.:
Code:
for (i=0; i<=3; i++) {
    zutaten = nachspeise[i] * p;
    printf("\n%.2f", zutaten);
}
Es ist in Ordnung, daß Du hinter "for" ein Leerzeichen gesetzt hattest, denn so kann man es von Funktionsaufrufen unterscheiden.
Grundsätzlich:
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway
;)
Zum Inhalt komme ich noch später. Jetzt erstmal essen (zweiter Weihnachtstag). :)
 
A

Anonymous

Gast
Ich hab das Thema mal nach "Konsole und Programmierung" verschoben.

prinzipiell für solche Dinge gilt in diesem Forum, wir unterstützen hier keine fehlende Eigeninitiative und machen hier für niemanden die Hausaufgaben, aber wir helfen gerne wenn es dabei hackt. Du hast dich ja schon sichtbar ausgiebig mit dem Thema befasst. Also werden wir hier selbstverständlich helfen.

Ein paar Dinge aber dennoch vorher. Das Programm ist vom Schreibstiel her wohl eines deiner ersten Programme und es gibt für solche Aufgaben immer hunderte Lösungswege. Auch haben wir hier im Forum zT User die sich professionell mit solchen Sachen befassen und dann auch entsprechende qualitative Vorschläge hier einbringen könnten. Es sollte auf jeden Fall verhindert werden, das wir dich mit zig verschiedenen Möglichkeiten komplett verwirren. Also mein Vorschlag der für alle Poster hier gelten sollte, wir helfen dir hier deinen Code so weit zu verbessern, dass er läuft und funktioniert und wir helfen nicht alle durcheinander. Wir wollen dir also nicht in Richtung einem Codes führen, der zwar nach allen Regeln der Programmierkunst perfekt ist, den du aber derzeit nicht mal ansatzweise versehen kannst.

Wenn du uns noch verraten könntest wie viel Kenntnisse und Erfahrungen in C oder einer anderen Programmiersprache du bisher schon hast, sprich ca. wieviel Lehrstunden oder welche Themen grob im großen und ganzen bisher vermittelt wurden. Würde uns sicherlich helfen uns auf dich und deinen Kenntnisstand einzustellen.

Jetzt überlassen wir erstmal abgdf das weiter Wort.

robi
 

framp

Moderator
Teammitglied
robi schrieb:
... und wir helfen nicht alle durcheinander ... Jetzt überlassen wir erstmal abgdf das weiter Wort.
Jupp, deshalb habe ich auch nicht meine Sicht der Dinge geschrieben :roll: Eine Sicht reicht völlig.
 
OP
D

dom

Newbie
hallo leute,
ihr seid super vielen dank für eure hilfe.

Also zu meinem programm mir ist klar das dieses programm sicher nicht euren ansprüchen gewachsen.
nachwievor bin ich insoweit stolz drauf da ich es komplett selber bearbeitet habe mit den vermitteltem wissen der hochschule.
so will ich ich kurz sagen was wir an der HS zum thema c gelernt haben und was auf dem lehrplan steht.
zu mir persönlich ich lerne c aus dem buch C PROGRAMMIEREN FÜR ANFÄNGER VON HELMUT ERLENKÖTTER,und habe keinerlei vorkenntnisse
zur vorlesung:
wir haben einen Vorlesungsblock und einen Übungsblock in dem diverse Übungsorogramme mit hilfe des Professors erstellt werden.
Grundlagen

Grundbegriffe der Programmierung

Einführung in die Programmiersprache C

Einfache Programmbeispiele

Lexikalische Konventionen

Datentypen und Variablen

Einführung in Pointer und Arrays

Anweisungen, Ausdrücke und Operatoren

Kontrollstrukturen

Blöcke und Funktionen

Fortgeschrittenes Programmieren mit Pointern

das ist original aus dem skript rauskopiert.

ich kann nur nochmal sagen vielen dank für eure hilfe ich habe sehr viel selber probiert und habe einige seiten durchforstet nur jetzt bin ich an meinem wissensende angekommen. oder sagen wir so ich weiß nicht mehr was kombiniert werden muss um ein "logisches" programm abzuliefern.
danke für die schon gegebenen tipps ich werde alles in meine korrektur und vorbereitung auf meine klausur einfliessen lassen.

schönen abend noch und mfg dom
 
A

Anonymous

Gast
ok abgdf hatte seine Chance und hat sie nicht genutzt, jetzt bin ich dran ;)


dom, du hast dich aus Unerfahrenheit vergaloppiert mit deinen Variablen. Das gehört zu den wichtigsten Vorarbeiten, das Problem analysieren und dabei feststellen wie sich die Zusammenhänge darstellen und wie man diese Zusammenhänge in Variablen möglichst günstig verpacken kann. Danach (eventuell auch parallel) kommt erst der Entwurf des Programmablaufes.

Dein Problem liegt hier:
Code:
Vorspeise[0]= 2;char string1[]="Tomate(n)";               //2 Tomaten
Vorspeise[1]= 1;char string2[]="Zwiebel(n)";               //1 Zwiebel
Vorspeise[2]= 1;char string3[]="EL Olivenoel";               //El olivenöl
Vorspeise[3]= 1;char string4[]="Zehe(n) Knoblauch";            //1 Zehe Knoblauch
Vorspeise[4]= 5;char string5[]="Gramm Pfeffer";               //5 g Pfeffer
Vorspeise[5]= 5;char string6[]="Gramm Salz";               //5 g Salz
Vorspeise[6]= 2;char string7[]="Scheiben Baguette";            //2 Scheiben Baguette
damit kannst du in einer Schleife zwar auf das Vorspeisenarray zugreifen, aber nicht auf die string?[] Variablen.
Code:
for (i=0;i<=6;i++) {
Zutaten=Vorspeise[i]*P;
printf("\n%.2f %s %s",Zutaten,string1,string2);   //das wird so nix, hast du ja auch so selbst festgestellt

Aber es ist noch nicht alles verloren, nur wird das Programm dadurch zwar funktionsfähig aber nicht schöner.
Arrays und Zeiger hast du schon mal was gehört. Deine string1[] ... string7[] sind an sich schon jeweils ein Array von Zeichen, deren Länge du bei der Initialisierung (also der Zuweisung = ) festlegst.
der Variabelname ohne die eckige Klammer ist ein Zeiger vom Type char* der dann auf das erste Zeichen dieses Arrays zeigt, soweit noch klar.

was du jetzt brauchst um zu einer schnellen Lösung zu kommen ohne das halbe Programm neu zu schreiben ist ein Array das als Elemente diese Variablen string1 .... string7 aufnehmen kann.
Also ein Array von Zeigern vom type char*
Code:
char *einheit[]={string1,string2,string3,string4,string5,string6,string7};
einheit[1] ist jetzt ein Zeiger char* auf den 2. String, also das selbe wie "string2"
einheit ist ein Zeiger char** also ein Zeiger auf einen Zeiger vom Type char.

zugreifen kannst du dann ganz einfach mit einheit wobei i von 0 bis 6 genau passend zu den Werten im Vorspeisenarray sind. Die Ausgabe kann kann dann also problemlos so hier erfolgen.
Code:
 case 1:
                        printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
                        scanf("%i",&P);
                        printf("\nSie benoetigen folgende Zutaten für die Vorspeise :\n");
                        for (i=0;i<=6;i++) {
                                Zutaten=Vorspeise[i]*P;
                                printf("\n%.2f %s",Zutaten, einheit[i]);      
                        }

                        break;

Das ist nicht ganz einfach zu verstehen mit dem "Array von Zeigern" oder "Zeiger auf Zeiger", aber das geht bei Strings oftmals nicht anders, da man hier eben sehr oft das Problem hat, das man nicht vorher die genaue Länge der einzelnen Strings kennt bzw diese sehr unterschiedlich ist und deshalb eben kein 2 dimensionales Array char[][] einrichten kann/will. Die Zeigerlänge ist aber konstant egal wie lang der String ist., also solche Zeiger bequem als Array einzurichten, und bei Strings dann auch bequem und einfach im Zugriff wie man in der printf-Zeile sehen kann.

Sobald du mal ein bisschen Zeit und Lust hast, dann können wir genau dieses Rezept-Problem ruig mal als Lehrstunde von ganz unten neu entwickeln. Damit du mal siehst wie man schon bei der Planung und Variabelnamen- und -type findung bestimmt, wie gut oder wie schlecht man an diesem Programm entwickeln und später erweitern kann und wie universell und wiederverwendbar die Einzelteile dabei werden können.


robi
 

abgdf

Guru
robi schrieb:
ok abgdf hatte seine Chance und hat sie nicht genutzt, jetzt bin ich dran ;)
Ich war halt noch Weihnachten feiern, aber Du kannst gern auch schonmal was schreiben, wenn Du möchtest. ;)
robi schrieb:
Auch haben wir hier im Forum zT User die sich professionell mit solchen Sachen befassen
Ok, ich sollte wohl für dom klarstellen, daß ich (leider) nicht zu diesen professionellen C-Programmierern gehöre, und daß mir C in den meisten Fällen einfach zu schwer ist, so daß ich meist in Python (oder Perl) schreibe, weil ich so sehr viel schneller vorankomme und dadurch als einzelner mehr (und dadurch größere) Aufgaben bewältigen kann.
Nach meinem Eindruck ist C im Grunde was für Profis und insbesondere auch für größere Teams von Profis. Oder wenn ein Programm unbedingt schnell sein muß. Was bei dem kleinen Kochbuch z.B. nicht der Fall wäre. Das vorweg. Dann also:
dom schrieb:
printf("\n%.2f %s %s",Zutaten,string1,string2); //## wenn man es so kompiliert schreibt er mir den string1,string2 untereinader,wie bekomme ich die zutaten passend zum float befehl? ich hoffe ihr versteht mich! ##
Man kann in C ein Array gleich ganz initialisieren, wenn man schon von Anfang an weiß, wie es aussehen soll.
Außerdem kann man mehrere Strings auch in einem zweidimensionalen Array von char speichern. Man kann dann auch auf diese Strings zugreifen, ohne schon in Zeigern denken zu müssen. Ich meine das so:
Code:
#include <stdio.h>

int main() {

    int vorspeise[7] = {2, 1, 1, 1, 5, 5, 2};
    char v_string[7][20] = {"Tomate(n)",
                            "Zwiebel(n)",
                            "EL Olivenoel",
                            "Zehe(n) Knoblauch",
                            "Gramm Pfeffer",
                            "Gramm Salz",
                            "Scheiben Baguette"};
    int v = 0;
    while (v < 1 || v > 7) {
        printf("Bitte waehlen Sie eine Vorspeisenzutat (1-7): ");
        scanf("%d", &v);
    }
    printf("Gewaehlt wurde: %d %s.\n", vorspeise[v - 1], v_string[v - 1]);
}
Ich hoffe, das vereinfacht einige Dinge in Deinem Programm. ;)
 

framp

Moderator
Teammitglied
Dann bringe ich auch noch meine Sicht der Dinge dazu:

Robi hat schon darauf hingewiesen, dass die Definition der Daten sehr wichtig ist und sein Aenderungsvorschlag benoetigt nur wenige Aenderungen in dem Code.

Mein Vorschlag erfordert eine ziemliche Aenderung. Im konkreten kleinen Beispiel ist es eigentlich overkill. Aber spaetestens wenn man groessere Programme schreibt geht das nur noch wenn man diesen Weg geht. Er basiert darauf, dass man Daten, die zusammengehoeren, auch zusammenfasst in einer Struktur fuer C (Kleine Intro dazu) und in objektorientierten Sprachen wie C++, Java oder Python in Klassen und zugehörigen Methoden. Ich kann nur empfehlen, den Weg frueh genug zu üben und zu lernen.

Anbei Beispielcode von mir (Die Gerichte würde ich bei den Ingredenzien allerdings so nicht essen. Sind nur rudimentär übernommen :-D ). Die Initialisierung der Daten ist krude und geht in anderen Programmiersprachen wie C++, Java oder Python wesentlich leichter.

Code:
/*kleines_kochbuch.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/**
 * Zutaten bestehen aus der Anzahl der Zutat und dem Namen 
 */

typedef struct{
	float anzahl;
	char *name;
} ZUTAT;

/**
 * Gerichte bestehen aus einem Namen und einer variablen Menge von Zutaten
 */

typedef struct{
	char *name;
	int anzahlZutaten;
	ZUTAT *zutaten[];
} GERICHT;

/**
 * Bruscetta
 */

ZUTAT tomate = { 2.0, "Tomate" };
ZUTAT zwiebel = { 6.0, "Zwiebel" };
ZUTAT knoblauch = { 10.0, "Knoblauch" };

GERICHT bruscetta = { "Bruscetta", 
				3,
				{ &tomate, &zwiebel, &knoblauch } 
				 };

/**
 * Pfannkuchen
 */

ZUTAT ei = { 5.0, "Ei" };
ZUTAT milch = { 2.9, "Milch" };

GERICHT pfannkuchen = { "Pfannkuchen", 
				2, 
				{ &ei, &milch } 
				 };

/*
 * Liste verfügbarer Gerichte
 */ 
GERICHT *gerichte[] = { &bruscetta, &pfannkuchen };

int main() {
	
	int i;
	for (i=0; i<sizeof(gerichte)/sizeof(gerichte[0]); i++) {			// Schleife ueber alle Gerichte
		printf("Gericht: %s\n", gerichte[i]->name);
	
		int j;
		for (j=0; j<gerichte[i]->anzahlZutaten; j++) {		// Schleife ueber alle Zutaten des i-ten Gerichts
			printf("Zutat: %s: %.2f\n", gerichte[i]->zutaten[j]->name, gerichte[i]->zutaten[j]->anzahl);
		}
		printf("\n");
	}
}
 
OP
D

dom

Newbie
wünsche einen guten abend,
so ich habe mir eure tipps angeschaut und musste erst step by step abarbeiten und nachvollzienen.
sieht so aus
lieber abgdf:
ich hab bestmöglich versucht umzusetzen was du mir geraten hast an dieser stelle, VIELEN DANK! :D

robi: geiler tipp ich habe das mit den pointern gehabt und dank dir auch endlich mal verstanden wie man es anwedet!
ich habe es auch angewendet und es funktioniert auch endlich das es passt . VIELEN DANK :D

framp: dein OVERKILL verstehe ich nicht aber ich werde es noch verstehen.
den du hast recht man sollte sich damit auseinandersetzen da ich im nächsten semstern OOP (JAVA) erlernen werde.
daher sollte ich mir das schon verinnerlichen und anwenden lernen.
dir auch vielen dank :D

allgemein muss ich sagen ich möchte das ganze noch besser verstehe. und ja ein kleines kochbuch zu programmieren war keine gute ideee:)
ich habe gemerkt was ihr damit meintet variablen richtig zu deklarieren.
bei meinen string deklararationen weerdet ihr sicher meine kreativität bemerken :D :???:
das programm sieht nicht gerade cool aus erfüllt aber die ansprüche meines profs.
natürlich bin ich über jedes feedback dankbar daher stell ich den code nochmal rein und
wenn ihr lust habt könnt ihr mich ruhig nochmal stutzen.
das ganze thema programmieren ist mir persönlich in soweit wichtig das ich nicht unwissend vor einem quellcode stehe.

noch einen schönen abend
mfg dom

Code:
/*kleines_kochbuch.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main() {

int R;
int P;
int i;
int z;

float vorspeise[7];
float hauptgericht[7];
float nachspeise[4];
float zutaten;


vorspeise[0]= 2; 					//2 Tomaten
vorspeise[1]= 1; 					//1 Zwiebel
vorspeise[2]= 1; 					//El olivenöl
vorspeise[3]= 1;				 	//1 Zehe Knoblauch
vorspeise[4]= 5; 					//5 g Pfeffer
vorspeise[5]= 5; 					//5 g Salz
vorspeise[6]= 2; 					//2 Scheiben Baguette	

char string1[]="Tomate(n)";
char string2[]="Zwiebel(n)";
char string3[]="EL Olivenoel";
char string4[]="Zehe(n) Knoblauch";
char string5[]="Gramm Pfeffer";	
char string6[]="Gramm Salz";
char string7[]="Scheiben Baguette";

char *einheit1[]={string1,string2,string3,string4,string5,string6,string7};


hauptgericht[0]=150;					//150g Kablbsschnitzel
hauptgericht[1]=1;					//1 Ei
hauptgericht[2]=60;					//60g Schmalz
hauptgericht[3]=0.25;					//0,25 Stück Zitrone
hauptgericht[4]=50;					//50g Mehl
hauptgericht[5]=50;					//50g Semmelbrösel
hauptgericht[6]=100;					//100g Kartoffeln

char stringk[]="Kablbsschnitzel";
char stringe[]="Ei(er)";
char strings[]="Gramm Schmalz";
char stringz[]="Stück Zitrone";
char stringm[]="Gramm Mehl";
char stringse[]="Gramm Semmelbrösel";
char stringka[]="Gramm Kartoffeln";

char *einheit2[]={stringk,stringe,strings,stringz,stringm,stringse,stringka};


nachspeise[0]=1;					//1 Ei
nachspeise[1]=100;					//100g Mehl
nachspeise[2]=125;					//125 ml Milch
nachspeise[3]=50;					//50g Marmelade ihrer Wahl

char stringei[]="Ei(er)";
char stringme[]="Gramm Mehl";
char stringmi[]="ml Milch";
char stringma[]="Gramm Marmelade ihrer Wahl";

char *einheit3[]={stringei,stringme,stringmi,stringma};



printf("\n\t\tKleines Kochbuch\n");
printf("\nZur Auswahl stehen 3 Rezepte :\n\n1.Bruschetta\n2.Kalbschnitzel mit Kartoffel\n3.Pfannkuchen\n");
printf("\nWaehlen Sie die Nummer ihres gewuenschten Rezeptes : ");
scanf("%i",&R);




switch (R) {

case 1:
printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
scanf("%i",&P);
printf("\nSie benoetigen folgende Zutaten für die Vorspeise :\n"); 
for (i=0;i<=6;i++) {
    zutaten = vorspeise[i] * P;
    printf("\n%.2f  \t%s",zutaten,einheit1[i]);
   }
									
break;
case 2:
printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
scanf("%i",&P);
printf("\nSie benoetigen folgende Zutaten für die Hauptspeise :\n");		
for (i=0;i <=6;i++) {
    zutaten = hauptgericht[i] * P;
    printf("\n%.2f \t%s",zutaten,einheit2[i]);
   }

break; 
case 3:
printf("\nBitte geben Sie die gewuenschte Anzahl der Personen an : ");
scanf("%i",&P);
printf("\nSie benoetigen folgende Zutaten für die Nachspeise :\n");								
for (i=0;i<=3;i++) {
    zutaten = nachspeise[i] * P;
    printf("\n%.2f \t%s",zutaten,einheit3[i]);
   }
break;

default:

if (R == 1||2||3) {
   printf("\nEs stehen nur 3 Rezepte zur Auswahl bitte nochmal Waehlen!\n");
  }
return 0;
break;

  } 
printf("\n\n\tViel Spaß bei der Zubereitung und guten Appettit!\n");
}
 

framp

Moderator
Teammitglied
dom schrieb:
framp: dein OVERKILL verstehe ich nicht aber ich werde es noch verstehen.
den du hast recht man sollte sich damit auseinandersetzen da ich im nächsten semstern OOP (JAVA) erlernen werde.
daher sollte ich mir das schon verinnerlichen und anwenden lernen.
Es gibt einen Unterschied zwischen Design und Implementierung. Meine Anregung gehört zum Design und ich hoffe dass Du nicht nur Programmierung lernst (wie es leider sehr häufig ist bei der IT Ausbildung) sondern auch Design.
 
OP
D

dom

Newbie
stimmt was mir als student auffällt ist das uns beigebracht wird kapiert das was da vorne steht, versucht so gut wie möglich zu programmieren- aussehen und logik ist fast schon nebensache.
ich sage das so -da das programmieren nicht hauptbestandteil meines studiums ist!
ich hab halt jetzt an meinem programm gesehen was eine gute struktur ausgemacht hätte...
 

abgdf

Guru
Also, ich hab' mir das inhaltlich noch mal genauer angesehen und verstehe das Konzept insgesamt leider nicht:
Du hast 3 Rezepte (Bruschetta, Kalbschnitzel mit Kartoffel, Pfannkuchen) und außerdem jeweils 3 Gänge (Vorspeise, Hauptgericht, Nachspeise).
Was erwartest Du z.B. bei der Nachspeise zum Pfannkuchen für eine Ausgabe? So wie ich das sehe, sind bisher nur die Hauptgänge implementiert, wobei die switch-Anweisung nach Gängen und nicht nach Gerichten unterscheidet, wie es laut Eingabeaufforderung aber eigentlich sein soll ...
Manchmal hilft es auch, das Ganze erstmal als Pseudocode zu formulieren. Bevor man sich dann in der Speicherverwaltung verhakt. :mrgreen:
 
OP
D

dom

Newbie
ich verstehe was du meinst...

ich musste bevor ich dieses prog. anfing ein struktogramm abgeben.(wurde vom prof zum glück abgesegnet)
so und jetzt das lustige:
das ganze projekt wird zu zweit bearbeitet ich hatte das glück einen kommilitonen abzubekommen
der noch weniger programmieren kanne als ich:)
aber leider hat er entschieden was wir programmieren sollen und hat somit das stuktogram eingereicht!
mein pech ich hab das soweit selber bearbeitet und verstehe bis jetzt den sinn eines solchen
kochbuchs nicht....
mir wäre es lieber zu VOR-HAUPT.&NACHSPEISE jeweils 3 gerichte anzubieten das man als KOCH
quasi wirklich eine auswahl hat und eine beliebige personenanzahl angeben kann.

ich muss damit es mehr sinn ergibt diese printf angaben so verändern damit man sich nicht mit vor,haupt &nachspeise verwirrt fühlt :)
witizg ist jeder tipp oder anmerkung führt dazu das man sich selber die frage stellt- VERDAMMT WAS HABE ICH DA GETAN???:)
 
A

Anonymous

Gast
Wenn man ein Programm erstellen will ist folgendes im Vorhinein schon mal Wichtig, egal wie klein das Projekt auch sein sollte.:

  • 1. Eine klar definierte Aufgabenstellung, mit einem reellem klar definierten angestrebtem Ergebnis
    2. Eine Analyse und Recherche zB. über die zu verarbeitenden Daten, deren Zusammenhänge und Wechselwirkungen, mögliche schon bestehende Teil-Lösungen & Lösungswege die man verwenden kann.
    3 Einen ganz groben Gesamtplan auf Modul- und Ablaufbasis
    4. Einen Stufenplan der Schritt für Schritt zum Ziel führt, es ist nicht sinnvoll das Programm gleich in aller Kompliziertheit komplett zu schreiben, mehrere/viele kleine Einzelschritte mit denen man immer Teilabschnitte des Programms ausgiebig testen kann und dann immer schrittweise neue Funktionalität dazu. Das ist einfacher zu entwickeln und macht die Fehlersuche einfacher, da die eigentliche Intelligenz in abgeschlossenen Einheiten gekapselt wird und man immer schon auf genügend stabilen und getesteten Code aufbauen kann, und nebenbei zwingt es zwangsläufig schon zu strukturiertem Programmieren.
    5. hier kommt dann schon mal die Auswahl für die geeignete Programmiersprache, Programmieroberfläche, eventueller geeignetem BasisGrafikKonzeptes usw.
    6. evtl. notwendig Unterteilung in Unterprojekte, grobe Beschreibung von evtl. benötigten Schnittstellen
    7 ........
bis hier her habe ich den Computer noch nicht mal hochgefahren, wenn man mal die Recherche im Netz nicht dazu zählt.

Das könnte dann zB so hier aussehen.
zu1. Aufgabe: Erstellen eines einfachen Linux-Konsolbasierenden elektronischen Kochbuches für wenige bis ein paar Hundert einfache Rezepte die aus Büchern, Fernsehen .... einfach übernommen werden können. Möglichkeit der Eingabe und Änderung der Rezepte, einfache Such- oder Filterfunktionen, zB "Hauptgang Fisch" oder "Nachtisch Obst", Rezeptauswahl aus Liste, Rezeptanzeige mit personenabhängiger Zutatenberechnung und Zubereitungshinweisen. Funktionell ja, aber wirkliche Praxistauglichkeit Nebensache, ich will programmieren lernen.

zu2.
  • * ein Kochbuch besteht aus einer Vielzahl von Rezepten
    * ein Rezept hat einen Namen, besteht aus mehreren Zutaten (genaue Anzahl sehr unterschiedlich), hat eine Beschreibung für die Zubereitung, jedes Rezept ist für eine bestimmte Personenzahl ausgelegt, gehört ordnungsmäßig immer in eine oder mehrere Kategorien
    * jede Zutat hat einen Namen, eine Mengenangabe und eine Maßeinheit
    * es existiert eine begrenzte Anzahl von Maßeinheiten, die zT unkompatibel sind, (Kilogramm Mehl in Litern angeben ? ), zT kompatibel und ineinander umrechenbar sind, zT aber kompativel und nicht genau umrechenbar sind.( zB 10* Messerspitze ist wieviel Teelöffel ?)


zu3.
Bei solchen kleinen Projekten kann das eine wilde Zeichnung auf einem Schmierzettel sein, sie muss genau so gut sein, dass du damit jemanden anders das Programm erklären kannst, zB um ihn zum Mitprogrammieren zu begeistern.
Einen wirklichen Zweck hat das Ding erstmal nicht, du wirst es hinterher nie wieder anschauen, mit großer Wahrscheinlichkeit das Endergebnis sogar anders funktionieren, aber der Versuch einer Bildlichen Darstellung ermöglichst es dir erst für dich selbst eine Vorstellung für das zu Erschaffene greifbar zu machen. Mit der entsprechenden Erfahrung wird hier die nackte Idee und Kreativität verschmelzen und lebendig, sowas hilft dir später (hoffentlich) bei komplexen Projekten die HauptLogic des Programmes zu erarbeiten und vor allzugroben globalen Denkfehlern zu bewahren.


zu4.
geplante Stufenentwicklung.
  • * Definition der internen Verarbeitungsstrukturen fur Zutaten , Rezept und Kochbuch
    * Funktionen um die Strukturen mit einigen Testrezepten statisch zu initialisieren
    * Ausgabe Funktionen
    * Einfache Ablaufsteuerung um Strukturen und Ausgabe zu testen
    * Verbessern und Vervollständigen der Ausgabefunktion
    * Format für Speicherung der Daten in Datei festlegen
    * Funktion für das Abspeichern der Statischen Daten in Datei
    * Funktion für das Einlesen der Daten aus Datei
    * Test der Ondateistruktur der Ein- und Ausgabe
    * Umbau von staitischer auf dynamischer Speicherverwaltung
    * Eingabefunktion für Rezept
    * Editierfunktion für Rezept
    * Such- oder Filterfunktion
    * Hauptmenu und Erscheinungsbild
    * Funktionstest
    * eventuell Hilfefunktionen
    * User Dokumentation erstellen
    * Praxis-und Abschlusstests

Und nach Punkt 4 der Stufenentwicklung haben wir dann in etwa die Funktion die dein Programm hat, nur sieht das Programm eben jetzt schon ganz anders aus..
Die etwas extensive Dokumentierung ist für alle Interessierten zum versuchen zu verstehen was dort im Einzelnen passiert.
(kleiner Hinweis für alle Ungeübten wie man mit solchen Code hier am Besten umgeht.
Aus dem Forum heraus kopieren und in eine "kochbuch.txt" speichern, diese Datei dann "kochbuch.c" umbenennen.
Beim anschauen zB mit vi oder KWrite wird jetzt das automatische Syntax Highlighting für Programmiersprache C aktiv und man erkennt die Struktur des Programmcodes besser.
Kompilieren geht mit "gcc kochbuch.c -o kochbuch" zum ausführen und ausprobieren dann einfach "./kochbuch"
)
Code:
/*kochbuch.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/* MAXREZEPT ist die maximale Anzahl der Rezepte die das Programm im Moment kennt*/
#define  MAXREZEPT 3


/* Die Defintion der derzeit bekannte Maßeinheiten
   die Zeiger auf die Namen sind in der Variabel mas[] hinterlegt*/
char *mas[9]={"Stück","Esslöffel","Gramm","Kilogramm","Scheibe"," ","ml","Liter","Zehe"};
/* für einfacheres Programmieren wird zusätzlich ein Aufzählungstype dafür eingeführt*/
enum e_heit {STUECK=0,ESSLOEFFEL=1,GRAMM=2,KILO=3,SCHEIBE=4,LEER=5,ML=6,L=7,ZEHE=8,};


/* Die Zutaten werden in einer Struktur verwaltet, und der DatenType "zutat" für diese Struktur definiert.*/
struct t_zutat {
        char* name;                   // Der Name der Zutat
        float einzel;                 // Die Menge als Gleitkommazahl
        enum e_heit einheit;          // Die Maßeinheit
};
typedef struct t_zutat zutat;



/* Die Rezepte werden auch in eine Struktur verpackt und Datentype "rezept" wird dafür definiert*/
struct t_rezept {
        char* name;                   // Der Name des Rezeptes
        int anzahl;                   // die Anzahl der Zutaten in diesem Rezept
        zutat  bestand[15];           // Ein Array vom type "zutat" soll die einzelnen Zutaten aufnehmen  
//      char* zubereitung;            // Reserviert für die Beschreibung der Zubereitung
//      char* klasse;                 // Reserviert für eine spätere Kategorisierung zB "Fisch Hauptgang"
        int gesamt;                   // die Anzahl der Personen auf die sich dieses Rezept bezieht
};
typedef struct t_rezept rezept;


/* Ein Array kochbuch aus Elementen "rezept" dient zur Aufnahme und internen Verarbeitung aller Rezepte */
rezept  kochbuch[MAXREZEPT];


/* Eine Unterfunktion für das Einlesen der Zutaten Daten in das Rezept, gehört zu temp Funktion fill_kochbuch() */
int fill_rezept(int r, int z, char* name, float m, enum e_heit e){
        // r ist die aktuelle  Rezeptnummer
        // z ist die aktuelle  Zutatennummer 
        kochbuch[r].bestand[z].name=name;             // name ist der Name der Zutat
        kochbuch[r].bestand[z].einzel=m;              // m ist die Menge als Zahl
        kochbuch[r].bestand[z].einheit=e;             // e ist der Aufzählungstype zur Maßeinheit
        return 0;
}


/* Temporäre Funktion zum Initalisieren und füllen des Kochbuches innerhalb des QuellCodes
   später soll diese Funktion die Daten aus einer Datei lesen können*/
int fill_kochbuch (void){
        kochbuch[0].name="Bruschetta";                      // REZEPT 0  Brushetta
        kochbuch[0].anzahl=7;                               // 7 Bestandteile
        kochbuch[0].gesamt=1;                               // Rezept ist für 1 Person
        fill_rezept(0,0,"Tomate(n)",1.0,STUECK);            //2 Tomaten
        fill_rezept(0,1,"Zwiebel(n)",1.0,STUECK);           //1 Zwiebel
        fill_rezept(0,2,"EL Olivenoel",1.0,ESSLOEFFEL);     //El olivenöl
        fill_rezept(0,3,"Zehe(n) Knoblauch",1.0,ZEHE);      //1 Zehe Knoblauch
        fill_rezept(0,4,"Gramm Pfeffer",5.0,GRAMM);         //5 g Pfeffer
        fill_rezept(0,5,"Gramm Salz",5.0,GRAMM);            //5 g Salz
        fill_rezept(0,6,"Scheiben Baguette",2.0,SCHEIBE);   //2 Scheiben Baguette
//-------------------------------------------------------------------------------


        kochbuch[1].name="Kalbschnitzel mit Kartoffel";     // REZEPT 1  Kalbsschnitzel
        kochbuch[1].anzahl=7;                               // 7 Bestandteile
        kochbuch[1].gesamt=1;                               // Rezept ist für 1 Person
        fill_rezept(1,0,"Kalbsschnitzel",.150,GRAMM);      //150g Kalbsschnitzel
        fill_rezept(1,1,"Ei(r)",1.0,LEER);                  //1 EI
        fill_rezept(1,2,"Schmalz",.06,GRAMM);               //60g Schmalz
        fill_rezept(1,3,"Zitronen Spalte",1.0,STUECK);      //1 Zitronenspalte
        fill_rezept(1,4,"Mehl",50.0,GRAMM);                 //50 g Mehl
        fill_rezept(1,5,"Semmelbrösel",50.0,GRAMM);         //50 g Semmelbrösel
        fill_rezept(1,6,"Kartoffeln",250.0,GRAMM);          //250g Kartoffeln
//-------------------------------------------------------------------------------


        kochbuch[2].name="Pfannkuchen";                       // REZEPT 2 Pfannkuchen
        kochbuch[2].anzahl=4;
        kochbuch[2].gesamt=4;                                //Rezeptur hier für 4 Personen
        fill_rezept(2,0,"Ei(er)",4,LEER);
        fill_rezept(2,1,"Mehl",.400,GRAMM);
        fill_rezept(2,2,"Milch",125,ML);
        fill_rezept(2,3,"Marmeldade",200,GRAMM);
//--------------------------------------------------------------------------------
// weitere Rezepte möglich, nicht vergessen auch  die Definition von MAXREZEPT dazu erhöhen

        return 0;
}


/* Funktion zu Ausgabe des Rezeptes */
int rezeptausgabe(int rez_nr, int pax){
        // rez_nr  ist die Nummer des Rezeptes das angezeigt werden soll
        // pax     ist die Anzahl der Personen für die das Rezept berechnet werden soll

        float menge;                                         // die berechnete Menge für eine Zutat
        int j;                                               // interne Laufzeitvariabel

        printf("\n %s \t%d Portionen\n----------------------------------------------------------------\n",kochbuch[rez_nr].name, pax);
        for (j=0;j<kochbuch[rez_nr].anzahl;j++){
                //Die Menge wird berechnet aus Rezepturmenge / die Rezepturgröße * die Menge der Personen
                menge = kochbuch[rez_nr].bestand[j].einzel / kochbuch[rez_nr].gesamt * pax ;


                //hier fehlt eine Funktion die Maßeinheiten umrechnet wenn die Werte zu groß werden (g->kg; ml->l; Teelöffel->Esslöffel ...) 
                //Auch Stück sollte immer eine Ganze Zahl sein, und auch keine halben Eier  ;-)


                // Ausgabe der Zutaten
                printf("%-20s \t %9.3f %s \n",kochbuch[rez_nr].bestand[j].name, menge , mas[kochbuch[rez_nr].bestand[j].einheit]);
        }
        printf("\n");
        return 0;
}

/* Hauptfunktion */
int main(void){
        int rez_nr = 0;                   // variable für die Rezepturnummer
        int pax;                          // variable für die Personenzahl
        int i;                            // Laufzeitvariable
        int eingabe;                      // Variable zur interaktiven Eingabe

        // zuerst muss das Kochbuch gefüllt werden mit den Rezepten
        fill_kochbuch();


        printf("\n\t\tKleines Kochbuch\n");
        printf("Zur Auswahl stehen %d Rezepte\n\n", MAXREZEPT);
        for (i=0; i<MAXREZEPT; i++){
                printf("   %3d \t %s\n",i, kochbuch[i].name);  // Ausgabe der Rezeptnamen
        }


        //Die Eingabe erfolgt in einer Schleife die nur mit einem gültigem EingabeWert verlassen werden kann
        do{
                printf("\n Bitte geben sie ihre Wahl als Zahl 0..%d ein  : ",MAXREZEPT -1 );
                scanf("%i", &eingabe);                          // Eingabe der Rezeptnummer  FIXME Fehler bei eingabe von Buchstaben
        }while( (eingabe < 0) || (eingabe >= MAXREZEPT));         // wiederholen bis eingabe zwischen 0 ... (MAXREZEPT -1) 
        rez_nr = eingabe;                                       // Eingabe an Rezeptnummer übergeben


        // Eingabe der gewünschten Personenzahl in Schleife bis gültiger Wert
        do {
                printf("\n Bitte geben sie die gewünschte Personenzahl ein : ");
                scanf("%i", &eingabe);                           // Eingabe Personezahl  FIXME Fehler bei eingabe von Buchstaben
        }while ((eingabe <= 0 ) || (eingabe > 200));             // wiederholen bis Eingabewert zwischen  1 ... 200 
        pax = eingabe;                                           // Eingabe an Variabele für Personenzahl übergeben


        // Ausgabe des Rezeptes
        rezeptausgabe(rez_nr, pax);


        printf("\n\tViel Spaß bei der Zubereitung und guten Appettit!\n\n");
        return 0;
}
//---------- END ----------------

Leider wird eine solche Herangehensweise selten gelehrt, das bekommt man am ehesten noch bei Praxis- oder Projektphasen nebenbei mit.
Wer ein paar Grundkenntnisse in C hat und gerne das Programmieren erlernen will, kann an dieser Stelle weitermachen, Aufgabe und Masterplan sind klar definiert und lassen genügend Spielraum.
Auch für andere Programmiersprachen durchaus geeignet, nur muss man da noch mal neu mit dem Code anfangen.

Einzureichen des Ergebnisses bis 30.06.2014 für Teilnahme am Preisausschreiben. akzeptiert wird alles was man auf jedem Rechner mit wenigen Handgriffen problemlos zum compilieren oder laufen bringt.
zB: Bash, C , C++, Perl , ...... auch AWK ;)

robi
 
Oben