Parser Schleife



  • Hallo zusammen,

    ich habe starke probleme eine schleife zu erstellen die mir das eingabeformat überprüft. Aufgabe ist so ein Nummerschild (ABDC-EF 1234)

    das spätere '-' und das spätere leerzeichen bereiten mir jedoch dabei noch mehr kopfzerbrechen.

    bin über eine schleife mit erklärung sehr dankbar.

    habs erst mit einer mit 'if' versucht...doch verläuft sich das irgendwie im untergrund

    Dazu muss gesagt werden, ich mach gerade eine kaufmännische ausbildung...doch muss ich jetzt komischerweise im betrieb 4monate programmieren.



  • Was habt ihr für komische Kennzeichen ???

    Schleifen sind ja schon und gut, aber ich sehe hier nicht wirklich einen Sinn darin, es mit einer Schleife zu tun (verbale Lösung):

    Ist erstes Zeichen != Buchstabe => Abbruch: Fehler
    Ist zweites Zeichen != Buchstabe => Abbruch: Fehler
    Ist drittes Zeichen != Buchstabe => Abbruch: Fehler
    Ist viertes Zeichen != Buchstabe => Abbruch: Fehler
    Ist fünftes Zeichen != '-' => Abbruch: Fehler
    Ist sechstes Zeichen != Buchstabe => Abbruch: Fehler
    Ist siebtes Zeichen != Buchstabe => Abbruch: Fehler
    Ist achtes Zeichen != ' ' => Abbruch: Fehler
    Ist neuntes Zeichen != Ziffer => Abbruch: Fehler
    Ist zehntes Zeichen != Ziffer => Abbruch: Fehler
    Ist elftes Zeichen != Ziffer => Abbruch: Fehler
    Ist zwölfes Zeichen != Ziffer => Abbruch: Fehler
    Ist Ende jetzt erreicht => Kennzeichen okay;



  • nabend,

    ja soo hab ich es ja auch versucht (mit lauter "if"). Es gerät außer kontrolle wenn ich eine nummer eingebe die weniger zeichen benötigt.

    z.B "A-E 1"

    Da jedes array feld ja nun mehrere zustände annehmen kann. Es kann also an stelle 3 des arrays buchstaben von a-z und ein "-" vorkommen.

    Dazu kommt noch ein problem, dass "scanf" beim einlesen einfach nach den ersten 2 "blöcken" aufhört und nicht wartet bis ich auf eingabe gedrückt habe.

    Es wird dabei nur "A-E" eingelesen, das leerzeichen versteht es scheints als stop.



  • raeyjey schrieb:

    nabend,

    ja soo hab ich es ja auch versucht (mit lauter "if"). Es gerät außer kontrolle wenn ich eine nummer eingebe die weniger zeichen benötigt.

    z.B "A-E 1"

    Da jedes array feld ja nun mehrere zustände annehmen kann. Es kann also an stelle 3 des arrays buchstaben von a-z und ein "-" vorkommen.

    Dazu kommt noch ein problem, dass "scanf" beim einlesen einfach nach den ersten 2 "blöcken" aufhört und nicht wartet bis ich auf eingabe gedrückt habe.

    Es wird dabei nur "A-E" eingelesen, das leerzeichen versteht es scheints als stop.

    Poste bitte mal den Teil deines Programms, wo du die Eingabe tätigst. Ich denke, da hast du auch was falsch gemacht.

    Ich fürchte, wenn du es mit einer Schleife probieren willst, wird so noch mehr außer Kontrolle geraten, da die da nichts zu suchen hat (es sei denn, du willst es besonders oder besonders schwierig machen.

    Du mußt dr vielleicht erst einmal nochmals grundlegende Gedanken machen, was man eingeben darf und was nicht.

    Deutsche Kennzeichen haben am Anfang 1 bis 3 (???) Buchstaben (Beispiel: KLE-...), danach kommt der '-' und nochmals ein oder zwei Buchstaben und zu guter letzt getrennt durch einen Leerschritt 1 bis 4 (???) Ziffern.

    1.Zeichen = Buchstabe => okay, sonst Fehler
    2. Zeichen = Buchstabe => okay
    3. Zeichen = Buchstabe => okay
    =>4. Zeichen muss '-' sein

    ODER:
    2. Zeichen = '-' => okay
    => 3. Zeichen muss Buchstabe sein
    ....

    Gibt halt viele Möglichkeiten, ist aber nur eine arbeitsintensive Aufgabe und weniger eine schwierige.



  • Zerlege den String mit strtok(string, " -") bzw. strtok(NULL, " -") in seine Bestandteile. Diese kannst Du dann jeweils in einer Schleife auf 'A' - 'Z' bzw. auf '0' - '9' testen.



  • hier die eingabe:

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    
    char kfz[128]="\0";     // Array mit 128 Felder
    int x;
    
    printf("Bitte geben Sie ihr zu ueberpruefendes Kfz-Kennzeichen ein!!!\n\n");
    printf("Achtung Eingabeformat: AAA-BB 1234\n");     // Hinweis auf Eingabeformat
        scanf("%s" ,&kfz);
    


  • #include <stdio.h>
    #include <string.h>
    
    int test_kennz(const char *k)
    {
    	char str[128];
    	int i, len, anz;
    	const char *ptr = k;
    	const char *tmp;
    
    	//evtl. führende Blanks überlesen - falls führende Blanks überhaupt erlaubt sind
    	while(*ptr == ' ')
    		++ptr;
    
    	strcpy(str, ptr);
    
    	len = strlen(str);
    
    	//evtl. Blanks am Ende ignorieren - falls die überhaupt erlaubt sind
    	while(len && str[len - 1] == ' ')
    		str[--len] = '\0';
    
    	if(str[0] < 'A' || str[0] > 'Z') //Kennzeichen beginnt nicht mit A - Z
    		return 0;                  
    
    	if(str[len - 1] < '0' || str[len - 1] > '9') //Kennzeichen endet nicht mit 0 - 9
    		return 0;
    
    	anz = 0;
    	for(i = 0; i < len; ++i)
    		if(str[i] == '-')
    			++anz;
    
    	if(anz != 1)    //Anzahl '-' nicht plausibel
    		return 0;
    
    	ptr = strchr(str, '-');
    
    	--ptr;
    
    	while(*ptr == ' ')  //falls vor dem '-' Blanks sein dürfen, diese überlesen
    		--ptr;
    
    	if(ptr - str > 4) // mehr als 4 Zeichen im ersten Block
    		return 0;
    
    	while(ptr > str)
    	{
    		if(*ptr < 'A' || *ptr > 'Z') //falsches Zeichen im ersten Block
    			return 0;
    		--ptr;
    	}
    	//erster Block in Ordnung
    
    	ptr = strchr(str, '-');
    	++ptr;
    
    	while(*ptr == ' ') //Blanks nach dem '-' überlesen (falls welche erlaubt sind)
    		++ptr;
    
    	//strcpy(str, ptr);
    	tmp = ptr;
    	ptr = strchr(tmp, ' ');
    	if(ptr == NULL)   //kein Blank hinter dem zweiten Block gefunden
    		return 0;
    
    	--ptr;
    
    	if(ptr - tmp > 4) // mehr als 4 Zeichen im zweiten Block
    		return 0;
    
    	while(ptr > tmp)
    	{
    		if(*ptr < 'A' || *ptr > 'Z') //falsches Zeichen im zweiten Block
    			return 0;
    		--ptr;
    	}
    	//zweiter Block in Ordnung
    
    	ptr = strchr(tmp, ' ');
    	++ptr;
    
    	while(*ptr == ' ') //Blanks nach dem ' ' überlesen (falls welche erlaubt sind)
    		++ptr;		
    
    	if(strlen(ptr) > 4) //mehr als vier Zeichen am Ende
    		return 0;
    
    	while(*ptr)
    	{
    		if(*ptr < '0' || *ptr > '9')
    			return 0;
    		++ptr;
    	}
    	//dritter Block in Ordnung
    
    	return 1;
    }
    
    int main(void)
    {
    	char kennz[128];
    
    	while(1)
    	{
    		printf("Kennzeichen eingeben:\n");
    		gets(kennz);
    
    		if(test_kennz(kennz))
    			printf("in Ordnung\n");
    		else
    			printf("fehlerhaft\n");
    	}
    }
    


  • Korhil schrieb:

    Schleifen sind ja schon und gut, aber ich sehe hier nicht wirklich einen Sinn darin, es mit einer Schleife zu tun:
    Ist erstes Zeichen != Buchstabe => Abbruch: Fehler
    Ist zweites Zeichen != Buchstabe => Abbruch: Fehler
    Ist drittes Zeichen != Buchstabe => Abbruch: Fehler
    Ist viertes Zeichen != Buchstabe => Abbruch: Fehler
    Ist fünftes Zeichen != '-' => Abbruch: Fehler
    Ist sechstes Zeichen != Buchstabe => Abbruch: Fehler
    Ist siebtes Zeichen != Buchstabe => Abbruch: Fehler
    Ist achtes Zeichen != ' ' => Abbruch: Fehler
    Ist neuntes Zeichen != Ziffer => Abbruch: Fehler
    Ist zehntes Zeichen != Ziffer => Abbruch: Fehler
    Ist elftes Zeichen != Ziffer => Abbruch: Fehler
    Ist zwölfes Zeichen != Ziffer => Abbruch: Fehler

    das sind immerhin zwölf tests auf ungleich mit dem jeweils nächsten zeichen. also so einfach würde ich hier eine schleifenlösung nicht abtun.
    🙂



  • #include <stdlib.h>
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    int isAllUpperAlpha(char* sequence) {
        while(*sequence) {
            if(!isupper(*sequence) && !isalpha(*sequence)) {
                return 0;
            }
            ++sequence;
        }
        return 1;
    }
    
    int isAllDigit(char* sequence){
        while(*sequence) {
            if(!isdigit(*sequence)) {
                return 0;
            }
            ++sequence;
        }
        return 1;
    }
    
    int main(void) {
        enum PART{ORT, ALPHA_ID, NUM_ID, ERROR};
        char input[13];
        char* token;
        enum PART part = ORT;
        fgets(input, 13, stdin);
        input[strlen(input) - 2] = '\0';
        for(token = strtok(input, " -"); token; token = strtok(NULL, " -")) {
            switch(part) {
            case ORT:
                if((strlen(token) > 3) || !isAllUpperAlpha(token)) {
                    part = ERROR;
                }
                else {
                    part = ALPHA_ID;
                }
                break;
            case ALPHA_ID:
                if((strlen(token) > 2) || !isAllUpperAlpha(token)) {
                    part = ERROR;
                }
                else {
                    part = NUM_ID;
                }
                break;
            case NUM_ID:
                if((strlen(token) > 4) || !isAllDigit(token)) {
                    part = ERROR;
                }
                break;
            default:
                break;
            }
        }
        if(part == ERROR) {
            printf("%s ist kein valides Kennzeichen.\n", input);
        }
        else {
            printf("%s ist ein valides Kennzeichen.\n", input);
        }
    
        return EXIT_SUCCESS;
    }
    


  • Belli schrieb:

    [..]
    		
    	if(ptr - str > 4) // mehr als 4 Zeichen im ersten Block
    
    [...]
    
    	if(ptr - tmp > 4) // mehr als 4 Zeichen im zweiten Block
    
    [...]
    

    Es muß hier heißen:

    if(ptr - tmp > 3)



  • Tachyon schrieb:

    [...]
    

    gibt unter anderem:

    UN - ID - - 250
    UN ist ein valides Kennzeichen.



  • Noch eine Alternative:

    int check_format( const char* str, const char* fmt )
    {
        while ( *str && *fmt )
        {
            // Buchstaben?
            if ( *fmt == 'A' )
            {
                if ( ! isalpha(*(str++)) )
                    return 0;
                while ( isalpha(*str) )
                    ++str;
            }
            // Ziffern?
            else if ( *fmt == 'N' )
            {
                if ( ! isdigit(*(str++)) )
                    return 0;
                while ( isdigit(*str) )
                    ++str;
            }
            // Sonstiges
            else
            {
                if ( *str != *fmt )
                    return 0;
                ++str;
            }
    
            ++fmt;
        }
        return *str=='\0' && *fmt=='\0';
    }
    
    int main()
    {
        int success = check_format( "ABDC-EF 1234", "A-A N" );
    }
    


  • hallo zusammen,

    vielen dank für die ganzen lösungen.

    ich werde aber denk ich einfach meinen code versuchen zu vervollständigen. is glaub kurz davor^^

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    
    char kfz[128]="\0";                                 // Array mit 128 Felder
    int x=0;
    int y=0;
    int z=0;
    int abbruch=0;
    int abbruch1=0;
    int abbruch2=0;
    int abbruch3=0;
    int abbruch4=0;
    int for1, for2, for3, for4, for5;
    
    printf("Bitte geben Sie ihr zu ueberpruefendes Kfz-Kennzeichen ein!!!\n\n");
    printf("Achtung Eingabeformat: AAA-BB 1234\n");
        gets(kfz);
    
            for(x=0;x<=2||abbruch==1;x++)
                {
                   if(kfz[x]>='A'&&kfz[x]<='Z')       // eingabe muss zwischen A und Z sein
                   {
                       for1==0;
                       abbruch==0;
                   }
                   else
                   {
                       abbruch==1;
                   }
               }
                   if(kfz[x]>='-')                // eingabe muss '-' sein
                   {
                       for2==0;
    
                   }
                   else
                   {
                       for2==1;
                   }
    
                  y=x+2;
    
            for(++x; x<=y||abbruch2==1;x++)
            {
                   if(kfz[x]>='A'&&kfz[x]<='Z')    // eingabe muss zwischen A und Z sein
                   {
                       for3==0;
                       abbruch2==0;
    
                   }
                   else
                   {
                       abbruch2==1;
                   }
    
            }
                   if(kfz[x]>=' ')                // eingabe muss ein leerzeichen sein
                   {
                       for4==0;
                   }
    
                   else
    
                   {
                       for4==1;
                   }
                z=x+4;
        for(++x; x<=y||abbruch4==1;x++)              // überprüft die eingabe zwischen feld 4 und 10 
            {
                   if(kfz[x]>='0'&&kfz[x]<='9')   // eingabe muss zwischen 0 und 9 sein
                   {
                       for5==0;
                       abbruch4==0;
                   }
                   else
                   {
                       abbruch4==1;
                   }
            }
    
          if (for1==0&&for2==0&&for3==0&&for4==0&&for5==0)
            {
                printf("Richtig");
            }
          else
            {
                printf("Bitte beachten Sie das Eingabeformat!!!");
            }
    
    }
    

    falls wer nochn kleinen tipp hat, ihr wisst ja....;D


Anmelden zum Antworten