C-Programm, das die Kopfzeile von C-Funktionen analysiert



  • Hallo zusammen,

    dies ist mein erstes Posting und ich stehe gleich vor einem Riesenpoblem. Wir haben in der letzten Woche begonnen in C zu programmieren und schreiben nun unsere ersten Programme. Jetzt hoffe ich, ich unterfordere Euch nicht und Ihr könnt mir trotzdem helfen.

    Die Aufgabe lautet:
    Schreiben Sie ein C-Programm, welches den Text einer Kopfzeile von
    C-Funktionen analysiert. Der Text der Kopfzeile soll als Zeichenkette
    eingegeben werden und untersucht werden. Als Ergebnis soll das Programm
    den Namen der Funktion, die Zahl der Parameter und die Parameternamen
    bestimmen.

    Beispiel:
    Für den Funktionsaufruf funk(a1,b1,u) soll folgende Ausgabe erzeugt werden:

    Name der Funktion: funk
    Zahl der Parameter: 3
    1.Parameter: a1
    2.Parameter: b1
    3.Parameter: u

    Hinweis:
    Da die Funktion scanf als Datentrennzeichen das Leerzeichen verwendet,
    eignet sich diese Funktion nicht zum Eingeben von Zeichenketten, welche
    auch Leerzeichen enthalten dürfen. Deshalb soll die Funktion gets
    verwendet werden, die eine Eingabezeile in eine Zeichenkette schreibt.

    Mein Lösungansatz sieht wohl bisher eher kläglich aus und gibt mir auch lediglich die komplette Zeichenkette wieder aus, weil ich nicht weiß, wie ich Werte aus ner Zeichenkette herausbekomme?

    /*
     * C-Programm zum Analysieren einer
     * Kopfzeile von C-Funktionen
     *
     * f=Funktion, i=Anzahl der Parameter, p=Paramter1,...
     */
    
    #include <stdio.h>
    
    void main()
    
    {
    	char f[100];
    	int i;
    	double p;
    
    	printf("\n Geben Sie Ihre Funktion in der Form: funktion(parameter1,parameter2,...) ein: ");
    	printf("\n ");
    	gets(f);
    	puts(f);
    
    system("pause");
    
    }
    

    Wäre für jegliche Art von Hilfe mehr als dankbar.



  • Okay, bin dann jetzt schon weiter, hab nur noch ein paar kleine Probleme.

    /*
     * C-Programm zum Analysieren einer
     * Kopfzeile von C-Funktionen
     *
     */
    
    #include <stdio.h>
    #include <conio.h>
    
    #define KLA 40
    #define KLB 41
    #define KOM 44
    #define SPA 0
    
    void main()
    
    {
    	char eingabestring[100],parameter[10][15],funktionsname[15];
    	int i=0,n=0,p=0,x=0,m=0,z1,z2;
    
    	for(z1=0;z1<10;z1++) for(z2=0;z2<15;z2++) parameter[z1][z2]=SPA;
    
    	printf("Geben Sie eine Funktion in der Form: Funktion(Paramter1,Parameter2,...) ein: ");
    	printf("\n\n");
    	gets(eingabestring);
    
    	while(eingabestring[i]!=KLA)
    	{
    		funktionsname[i]=eingabestring[i];
    		i++;
    	}
    
    	funktionsname[i]=SPA;
    	i++;
    
    	while(eingabestring[i]!=KLB)
    	{
    		if(eingabestring[i]==KOM)
    		{
    			parameter[n][p]=SPA;
    			n++;
    			i++;
    			p=0;
    		}
    
    		if(eingabestring[i]!=KOM)
    		{
    			parameter[n][p]=eingabestring[i];
    			p++;
    			i++;
    		}
    	}
    
    	printf("\n\nDie Funktion heisst: ");
    	puts(funktionsname);
    
    	printf("\nParameteranzahl: %d",n+1);
    	printf("\n");
    
    	for(m=0;m<=n;m++)
    	{
    		printf("\n %d.te Parameter: ",m+1);
    
    		for(x=0;x<=p;x++)
    		{
    			if(parameter[m][x]==KLB)parameter[m][x]=0;
    			if(parameter[m][x]!=SPA)
    				printf("%c",parameter[m][x]);
    		}
    	}
    	printf("\n\n");
    	system("pause");
    }
    

    1.) Wenn ich die Form nicht beachte, hängt sich das Programm auf. Wie kann ich das verhindern?
    2.) Wenn ich z.B. sin() eingebe, müsste die Parameteranzahl 1 sein, aber der Parameter 0. Wie kann ich das lösen?



  • Problem 2 ist jetzt auch gelöst. 😉 Die 0 erscheint.

    Jetzt fehlt nur noch die Überprüfung, ob die Form funk(p1,p2,...) beachtet wurde. Hat jemand ne Idee? Ich dachte, ich könnte das mit strlen regeln, aber da hängt sich alles auf. 🙄



  • Nach Bücherlesen hab ich's jetzt gepackt... puh. 🙂

    Hatte die #include <string.h> vergessen, weshalb auch strlen nicht funktioniert hat. 🙄 Habe es jetzt aber nicht über strlen, sondern mit strchr gelöst, indem ich noch einen char eingeführt habe und den eingabestring auf Klammern untersuchen lasse. Wenn sich der User einigermaßen an meine Vorgaben hält, also z.B keine Funktion(,) eingibt, dann gibt's jetzt auch keine Abstürze mehr.
    Die Klammern kann er ruhig weglassen, dann haut's ihm meine Fehlermeldung um die Ohren 😉 , aber sobald er nur ein Komma als Parameter in der Klammer angibt oder nach dem letzten Komma kein Parameter mehr folgt, hängt's sich wieder auf.



  • Das nenn ich mal Selbstbildung 👍🙂

    MfG SideWinder



  • Hehe, und es gab das gewisse Aha-Erlebnis. 💡 😉



  • @Strenni
    Trotzdem noch 2 Tipps:

    1. Verwende nicht gets() sondern fgets() (das kannst auch deinem Lehrer sagen). Denn bei gets() besteht die Gefahr eines Bufferoverflows, da du die Eingabe nicht begrenzen kannst. D. h. wenn jemand mehr als 99 Zeichen bei deinem Programm eingibt, dann kann es zu seltsamem Verhalten des Programms kommen. Bei fgets() schränkst du die Anzahl der Zeichen ein, die in den Puffer geschrieben werden dürfen und somit wird auch nicht über die Grenze des Puffers hinausgeschrieben.

    2. Verwende am besten nicht system("pause") oder andere Konsolenbefehle. Das ist die schlechteste und umständlichste Art (für das Programm) eine beliebige Eingabe vom Benutzer zu erzwingen. Verwende doch einfach eine normale Eingabefunktion. In der FAQ findest du unter "Automatisches Schließen verhindern" mehr zu dem Thema.



  • Danke schön AJ, das werd ich direkt noch abändern. Hab eh schon von nem Kumpel zu hören bekommen, dass mein Programmierstil total sch... aussieht. 😉 Aber was erwartet man schließlich von nem Anfänger, hehe.

    Heute gab es übrigens die nächste Aufgabe, die mich wieder vor allerhand Probleme stellt. Werd mich jetzt erstmal wieder in meine Bücher vergraben und probieren... 😉



  • das sieht gar nicht so schlecht aus. aber ein paar anmerkungen habe ich doch:

    1. verwende klare bezeichner. es ist nichts dagegen einzuwenden, gelegentlich für kleine überschaubare schleifen einfach mal i,jk oder x,y,z zu verwenden; für alles andere ist eine eindeutige namenswahl unverzichtbar, man kann ja nicht jedesmal das gesamte program analysieren, um zu verstehen, wozu nun eine bestimmte variable dient.

    2. obiges gilt natürlich auch für #define ; hier brauchst du diese aber gar nicht (ausser evtl. für das null-zeichen, wenn du keine escape-sequencen verwenden willst). druckbare zeichen kannst du immer auch mit '' definieren. ein

    eingabestring[i]!='('
    

    ist einfach viel klarer als ein

    eingabestring[i]!=KLA
    

    auch (und gerade) bei #defines gilt: der name richtet sich nach der verwendung, nicht nach dem konkreten wert, den er repräsentiert:

    #define EINS 1
    

    ist ziemlich sinnlos.

    #define STRING_TERMINATOR '\0'
    

    kann dagegen nützlich sein.

    3. main() ist jetzt schon recht lang geworden. es könnte also sinnvoll sein, die analyse des eingabestrings in eine eigene funktion zu verlagern. das steigert die übersichtlichkeit. der einfachheit halber kannst du bei solch wenig komplexen programmen ohne weiteres globale variablen verwenden, um daten zwischen main und der funktion auszutauschen.


Log in to reply