Zeichenkette analysieren ??



  • Eleganter geht das natürlich mit switch().

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    void analyze(char *pszString)
    {
    	// Dublikat anlegen
    	//
    	char *pszInput = (char *) malloc(strlen(pszString) + 1);
    	if (pszInput == NULL)
    	{
    		puts("Nicht genuegend Speicher vorhanden!");
    		exit(EXIT_FAILURE);
    	}
    	strcpy(pszInput, pszString);
    
    	char *pszPart = pszInput;
    	int nr_param = 0;
    	int nr_open = 0;
    	int pos_first = 0;
    
    	printf("Zu analysieren: %s\n\n", pszInput);
    
    	// Leerzeichen entfernen (falls vorhanden)
    	//
    	int i = 0, j = 0;
    	while (pszInput[i])
    	{
    		if (pszInput[i] != ' ')
    		{
    			pszInput[j++] = pszInput[i];
    		}
    		i++;
    	}
    	pszInput[j] = '\0';
    
    	// Analyse bzw. Zerlegung
    	//
    	int length = strlen(pszInput);
    	for (int i = 0; i < length; i++)
    	{
    		switch (pszInput[i])
    		{
    			case '(':
    				if (nr_open == 0)  // erste öffnende Klammer?
    				{
    					pszInput[i] = '\0';
    					printf("Name der Funktion: %s\n", pszInput);
    					pszPart = pszInput+i+1;
    
    					pos_first = i;
    				}
    				nr_open++;
    				break;
    
    			case ',':
    				if (nr_open == 1)   // oberster Level?
    				{
    					nr_param++;
    
    					pszInput[i] = '\0';
    					printf("%d. Parameter: %s\n", nr_param, pszPart);
    					pszPart = pszInput+i+1;
    				}
    				break;
    
    			case ')':
    				if (nr_open == 1)   // letzte schließende Klammer?
    				{
    					if (i - pos_first > 1)    // Parameterliste nicht leer?
    					{
    						nr_param++;
    
    						pszInput[i] = '\0';
    						printf("%d. Parameter: %s\n", nr_param, pszPart);
    					}
    					goto end;   // Abbruch der Schleife
    				}
    				nr_open--;
    				break;
    		}
    	}
    	end:
    	printf("Zahl der Parameter: %d\n\n", nr_param);
    
    	free(pszInput);
    }
    
    int main(void)
    {
    	char szInput[256];
    
    	strcpy(szInput, "func(p1(a,b(c,d)),p2,p3(e))");
    	analyze(szInput);
    
    	strcpy(szInput, "f(p1,p2)g()");
    	analyze(szInput);
    
    	strcpy(szInput, "clear( )");
    	analyze(szInput);
    
    	return 0;
    }
    


  • geht sogar nochn einfacher :

    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    char funktion[];
    int i=0,d=1,ende=0;
    main()
    
    {
        printf("Funktion :"); gets(funktion);
    
    printf("Name der Funktion : ");
             do
             {
                      printf("%c%",funktion[i]);i++;
             }while(funktion[i]!='(');
    i++;
    do
    {
    printf("\n%i.Parameter : ",d);
             do
             {
                      printf("%c%",funktion[i]);
                      i++;
                      if (funktion[i]==')')
                      {
                         funktion[i]=(',');
                         ende=1;
                      }
             }while(funktion[i]!=(','));
             i++;
             d++;
    }while(ende==0);
    getch();
    }
    


  • zeisesoft2000 schrieb:

    geht sogar noch einfacher

    Ah ja? Hast Du Dein "C-Programm" eigentlich auch schon mal getestet? 👎

    Noch ein kleiner Hinweis: die grundlegende Struktur eines C-Programms (also das allereinfachste "Basisprogramm") ist:

    int main(void)
    {
        /* Code */
    
        return 0;
    }
    

    (void kann hier auch weggelassen werden, int jedoch nicht.)



  • EinGast schrieb:

    Hast Du Dein "C-Programm" eigentlich auch schon mal getestet?

    Hinweis, der OP schrieb:

    Es geht darum den Text einer Kopfzeile von C-Funktionen zu analysieren.
    Der Text der Kopfzeile soll als Zeichenkette eingeben 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
    1.Parameter: a1
    2.Parameter: b1
    3.Parameter: u
    Zahl der Parameter: 3

    Da hier ganz allgemein von C-Funktionen bzw. Funktionsaufrufen die Rede ist, sollten die Testdaten in jedem Fall umfassen:

    funk()
    funk(a)
    funk(a,b)

    aber auch ein Aufruf wie der folgende ist zulässig:

    funk(f(a,b),c)
    etc.

    (Ich habe die Aufgabe -aufgrund des angegebenen Beispiels- so aufgefasst, dass es hier um die Analyse von Funktionsaufrufen geht, auch wenn der OP geschrieben hat: "Es geht darum den Text einer Kopfzeile von C-Funktionen zu analysieren." - sein Beispiel zeigt das aber anders.)



  • Die Funktion soll nur als einfacher Text eingegeben werden.
    Es geht also nur darum eine Zeichenkette anhand von markanten Zeichen zu zerlegen.

    Hier wäre das z.B.: die " ( " die uns sagt wo der Name der Funktion aufhört und wo die Werte (Variablen) anfangen.

    Und die " , " würden uns zeigen wann ein Wert zu ende ist und wo ein neuer anfängt.

    und so weiter ...

    nun ja aber wie sätze ich sowas in C um ?????? 😕



  • ector1084m schrieb:

    Die Funktion soll nur als einfacher Text eingegeben werden.
    Es geht also nur darum eine Zeichenkette anhand von markanten Zeichen zu zerlegen.

    Ja, ja, das ist schon klar. 🙂

    Hier wäre das z.B.: die "(" die uns sagt wo der Name der Funktion aufhört und wo die Werte (Variablen) anfangen.

    Ja, sehr gut, so kann man das machen!

    Und die "," würden uns zeigen wann ein Wert zu ende ist und wo ein neuer anfängt.

    Ja, genau.

    nun ja aber wie setze ich sowas in C um ?????? 😕

    In solchen Fällen ist es immer gut, methodisch vorzugehen.

    Am Besten, Du zerlegst das Problem in 1. eine Funktion, die das gewünschte leisten soll, und 2. das rufende Hauptprogramm, das die Daten liefert, und die Funktion (damit) aufruft.

    Dann hätten wir also erst mal ein ganz einfaches Hauptprogramm (für Testzwecke):

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        char szInput[256];
    
        strcpy(szInput, "f(a,b,c)");
        analyze(szInput);
    
        return 0;
    }
    

    Unsere Funktion soll also "analyze()" heißen.

    Tja, und wie sieht analyze() nun aus?

    Hier eine mögliche Lösung, die im wesentlichen das umsetzt, was Du oben beschrieben hast. Dabei wird mit Pointern gearbeitet, und der Umstand genutzt, dass für C ein String zuende ist, wenn es auf das das Zeichen '\0' stößt!

    Was also gemacht wird, ist, dass der Reihe nach die Trennzeichen '(', und ',' durch '\0' ersetzt werden. Und ein Pointer jeweils auf den Beginn, des nächsten "Abschnittes" in dem String zeigt. [...]

    void analyze(char *pszString)
    {
        char *pszPartBegin = pszString;   // Beginn des Strings
        int nr_param = 0;
    
        printf("Zu analysieren: %s\n\n", pszString);
    
        int length = strlen(pszString);
    
        for (int i = 0; i < length ; i++)
        {
            if (pszString[i] == '(')
            {
                pszString[i] = '\0';
                printf("Name der Funktion: %s\n", pszString);
                pszPartBegin = pszString+i+1;   // neuer Abschnitt
            }
    
            if (pszString[i] == ',')
            {
                nr_param++;
    
                pszString[i] = '\0';
                printf("%d. Parameter: %s\n", nr_param, pszPartBegin);
                pszPartBegin = pszString+i+1;   // neuer Abschnitt
            }
    
            if (pszString[i] == ')')
            {
                nr_param++;
    
                pszString[i] = '\0';
                printf("%d. Parameter: %s\n", nr_param, pszPartBegin);
            }
        }
        printf("Zahl der Parameter: %d\n\n", nr_param);
    }
    

    (*Bitte nicht einfach blind kopieren und abgeben!*)

    So weit so gut. Das Programm (die Funktion) hat aber noch eine ganze Reihe kleiner Schönheitsfehler; es gibt also noch einiges zu tun... 😉

    Es funktioniert lediglich für Funktionsaufrufe der Form

    funk(a_1, ..., a_n)

    wo n >= 1 ist, und die a_i einfache Variablen bzw. Konstanten bezeichnen.

    Bei dem Aufruf

    funk()

    scheitert es aber schon. Das wäre also der nächste Schritt (das zu implementieren)!

    Und mit Aufrufen der Form

    funk(funk2(a, b), c)

    etc. kommt das Programm natürlich auch (noch) nicht zurecht.

    Na dann knobel mal schön... :p



  • ich habe jetzt selber mal rum probiert und ne Lösung gefunden ...
    Problem meiner Lösung ist ... das die Syntax immer gleich sein muss, soll heißen das ich keine Fehlerüberprüfung habe.
    ist sicher auch kein toller programmierstil aber es geht halt erstmal.

    #include <stdio.h>
    #include <string.h>

    int main(void)
    {
    char buf[100];
    int ap=0,ch1t=0,i=0,ch1=',',p=1;

    printf("Funktion : "); gets(buf);

    if(strchr(buf, ch1))
    {
    ch1t=1;
    }

    if(ch1t=1)
    {
    do
    {
    if(buf[i]==',')
    {
    ap=ap++;
    }
    i++;
    }
    while(buf[i]!='\0');
    }
    else ap=1;
    system("cls");
    i=0;
    printf("Name der Funktion: ");

    do
    {
    printf("%c",buf[i]);
    i++;

    }
    while(buf[i]!='(');
    i++;
    printf("\nZahl der Parameter: %d",ap+1);
    printf("\n%d.Parameter: ",p);
    do
    {
    if(buf[i]!=',')
    {
    printf("%c",buf[i]);
    i++;
    }
    else{
    printf("\n%d.Parameter: ",p);
    p++;i++;}

    }
    while(buf[i]!=')');
    printf("\n\n\n");
    getch();
    }



  • ector1084m schrieb:

    ich habe jetzt selber mal rum probiert und ne Lösung gefunden ...

    Ja, gut, dass Du es selbst probiert hast! (Unten eine Version in der ich die gröbsten Schnitzer beseitigt habe.)

    Problem meiner Lösung ist ... das die Syntax immer gleich sein muss, soll heißen das ich keine Fehlerüberprüfung habe.

    Ja, allerdings habe ich das auch nicht gemacht (in meiner Lösung). Ein größeres Problem sehe ich darin, wie das Programm die Eingabe "f()" verarbeitet.

    Kurz noch etwas zu Deinen Fehlern bzw. den Unschönheiten Deines Programms:

    Einmal hattest Du "if (ch1t=1)", das muss natürlich "if (ch1t == 1)" heißen. 🙂
    Dann hattest Du "ap=ap++;" - urgs! Es muss hier ap++ heißen.
    sdtlib.h soltest Du includieren (wegen des system()-Befehls).
    ',' ist in meinen Augen (primär) ein char und kein int.
    Etwas aussagekräftigere Variablennamen können auch nie schaden.
    Die Konstruktion mit ch1t=1; [...] ist überflüssig: weglassen!
    Auf if (strchr(buf, trenn)) kann man dann auch verzichten. 🙂

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(void)
    {
    	char buf[100] = "funk(a1,a2,b1,u)";
    	int anz_param = 1, i_param = 1;
    	char trenn = ',';
    
    	// printf("Funktion : ");
    	// gets(buf);
    
    	int i = 0;
    	do
    	{
    		if (buf[i] == trenn)
    		{
    			anz_param++;
    		}
    		i++;
    	}
    	while (buf[i] != '\0');
    
    	system("cls");    // Vorsicht, fkt. nur unter DOS/Windows
                          // unter Linux: system("clear");
    	i = 0;
    	printf("Name der Funktion: ");
    
    	do
    	{
    		printf("%c", buf[i]);
    		i++;
    	}
    	while (buf[i] != '(');
    	i++;
    
    	printf("\nZahl der Parameter: %d", anz_param);
    
    	printf("\n%d. Parameter: ", i_param);
    	do
    	{
    		if (buf[i] != trenn)
    		{
    			printf("%c", buf[i]);
    			i++;
    		}
    		else
    		{
    			i_param++;
    			printf("\n%d. Parameter: ", i_param);
    			i++;
    		}
    	}
    	while (buf[i] != ')');
    
    	printf("\n\n\n");
    
    	return 0;
    }
    

    Es bleibt das "unschöne" Verhalten des Programms bei der Eingabe "funk()" - das solltest Du noch eliminieren. 👍



  • #include <stdio.h>
    #include <string.h>

    void main()
    {
    char buf[100];
    int ap=1,ch1t=0,i=0,ch1=',',p=1;

    printf("Funktion : "); gets(buf);

    if(strchr(buf, ch1))
    {
    ch1t=1;
    }

    if(ch1t=1)
    {
    do
    {
    if(buf[i]==',')
    {
    ap=ap++;
    }
    i++;
    }
    while(buf[i]!='\0');
    }

    i=0;

    printf("Name der Funktion: ");

    do
    {
    printf("%c",buf[i]);
    i++;
    }
    while(buf[i]!='(');

    i++;
    if(buf[i]!=')')
    {
    printf("\nZahl der Parameter: %d",ap);
    printf("\n%d.Parameter: ",p);

    do
    {
    if(buf[i]!=',')
    {
    printf("%c",buf[i]);
    i++;
    }
    else
    {
    p++;
    printf("\n%d.Parameter: ",p);
    i++;
    }

    }
    while(buf[i]!=')');
    }
    else printf("\n\nEs wurden keine Parameter angegeben!");

    printf("\n\n");

    }



  • EinGast schrieb:

    [hier] eine Version in der ich die gröbsten Schnitzer beseitigt habe.

    Einen g a n z wichtigen Punkt aber hatte ich vergessen zu erwähnen: NIEMALS "gets()" für die Eingabe von Daten benutzen!

    Besser so:

    #define SIZE 256
    
    int main(void)
    {
    	char buf[SIZE] = "";
    
    	:
    
    	printf("Funktion: ");
    	fgets(buf, SIZE, stdin);
    
    	:
    


  • ector1084m schrieb:

    ist sicher auch kein toller programmierstil [...]

    Stimmt. 😃

    Ich habe jetzt mal Deine Vorlage genommen, das Ganze noch ein wenig "gestrafft", und durch entsprechende Abfragen verhindert, dass das Programm über den zulässigen Bereich des Buffers hinausschreibt ⚠ . Auch funk() funktioniert jetzt. 🙂 (Nicht aber funk( ) - man muss also noch vor der eigentlichen Verarbeitung des Eingabe die Leerzeichen entfernen. Das sollte aber kein Problem sein.)

    #include <stdio.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define SIZE 256
    
    int main(void)
    {
        char buf[100] = "";
        int i_param = 1;
        char trenn = ',';
    
    	printf("Funktion: ");
        fgets(buf, SIZE, stdin);
    
        printf("Name der Funktion: ");
    	int i = 0;
        do
        {
            printf("%c", buf[i]);
        }
        while (buf[++i] != '(' && buf[i] != '\0');
    
    	if (buf[i] == '\0')
    	{
    		printf("\nFEHLER: Funktionsname zu lange!\n");
    		exit(EXIT_FAILURE);
    	}
    
    	if (buf[++i] == ')')
    	{
    		printf("\nZahl der Parameter: 0\n");
    		exit(EXIT_SUCCESS);
    	}
    
        printf("\n%d. Parameter: ", i_param);
        do
        {
            if (buf[i] != trenn)
                printf("%c", buf[i]);
            else
    			printf("\n%d. Parameter: ", ++i_param);
        }
        while (buf[++i] != ')' && buf[i] != '\0');
    
        printf("\nZahl der Parameter: %d\n", i_param);
    
        return 0;
    }
    


  • EinGast schrieb:

    Ich habe jetzt mal Deine Vorlage genommen, das Ganze noch ein wenig "gestrafft", und...

    ...dabei einen dummen Fehler eingebaut, sorry! 😞

    Statt "char buf[100]" muss es natürlich heißen "char buf[SIZE]". ⚠

    Der Code beginnt also dann folgendermaßen (ein stdio.h war auch zuviel includiert):

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define SIZE 256
    
    int main(void)
    {
        char buf[SIZE] = "";
        int i_param = 1;
        char trenn = ',';
    
        printf("Funktion: ");
        fgets(buf, SIZE, stdin);
    
        :
    

    Ok, genug C/C++ für heute. 🙂



  • Ich bedanke mich für eure nette und schnelle Hilfe!

    Habe jetzt die Lösung von "EinGast" übernommen.
    (Mir wurden zwar noch 2 Fehler angezeigt aber die waren schnell behoben)

    Meine Version war ja schon nah dran was gutes zu werden 😃 aber die letzte Variante von "EinGast"(01:49:33 26.01.2005 Titel: Re: mein ergebnis)
    fand ich dann doch besser 👍

    OK viel spaß noch und big THX !!!! 😃


Anmelden zum Antworten