Rudimentärer Eingabe-Parser



  • Hi(gh)!

    Ich nehme jetzt in meinem Klima-Datenprogramm die Sortieren-Funktion für die Datensätze in Angriff... als Erstes wird der Benutzer nach dem primären und sekundären Sortierfeld gefragt:

          case '4':
    	do
    	{  
    	  printf("\nErstes Feld, nach dem sortiert werden soll: ");
    	  fgets(feld1, 23, stdin);
    	  feld1[strlen(feld1)-1]='\0'; // Zeilenumbruch wird mit Stringende-Null überschrieben	
    	  if (feldparser(felder, feld1) == false)
    	  {  
    	    printf("\nDieses Feld existiert nicht! Bitte eines der folgenden Felder eingeben:\n");
    	    felderausgabe(felder);
    	  } 
    	}
    	while (feldparser(felder, feld1) == false);
    	do
    	{  
    	  printf("\nZweites Feld, nach dem sortiert werden soll: ");
    	  fgets(feld2, 23, stdin);
    	  feld2[strlen(feld2)-1]='\0'; // Zeilenumbruch wird mit Stringende-Null überschrieben	
    	  if (feldparser(felder, feld2) == false)
    	  {  
    	    printf("\nDieses Feld existiert nicht! Bitte eines der folgenden Felder eingeben:\n");
    	    felderausgabe(felder);
    	  }
    	  else if (strcmp(feld1, feld2) == 0)
    	    printf("\nDie beiden Felder dürfen nicht identisch sein!\n");  
    	}
    	while (feldparser(felder, feld2) == false || strcmp(feld1, feld2) == 0);
    
    

    Das Array mit den Feldernamen ist in main definiert:

    char* felder[]={ "Station", "Land", "Region", "Breite", "Länge", "Höhe", "Klimaperiode_Beginn", "Klimaperiode_Ende", "Temperatur_Januar", "Temperatur_Februar", "Temperatur_März", "Temperatur_April", "Temperatur_Mai", "Temperatur_Juni", "Temperatur_Juli", "Temperatur_August", "Temperatur_September", "Temperatur_Oktober", "Temperatur_November", "Temperatur_Dezember", "Niederschlag_Januar", "Niederschlag_Februar", "Niederschlag_März", "Niederschlag_April", "Niederschlag_Mai", "Niederschlag_Juni", "Niederschlag_Juli", "Niederschlag_August", "Niederschlag_September", "Niederschlag_Oktober", "Niederschlag_November", "Niederschlag_Dezember", "Temperaturmittel", "Niederschlagssumme", "Klimaformel", "Quelle" };
    

    Die Funktion feldparser() überprüft die beiden Eingaben auf Gültigkeit:

    bool feldparser(char** fields, char* field)
    {
      bool match = false;
      unsigned char i; // Zählvariable
      for (i=0; i<36; i++)
        if (strcmp(fields[i], field) == 0)
          match = true;
        
      return match;
    }
    
    

    Die Funktion felderausgabe() gibt im Falle einer Falscheingabe die Namen der gültigen Felder aus:

    void felderausgabe(char** fields)
    {
      unsigned char i; // Zählvariable
      for (i=0; i<36; i++)
        printf("%s\n", fields[i]);
    }
    

    klima.c kompiliert mit den neuen Funktionen einwandfrei, und ihre Aufrufe tun auch das, was sie sollen.

    Verbesserungsvorschläge?

    Bis bald im Khyberspace!

    Yadgar



  • Wenn du den match hast, kannst du die Schleife auch gleich beenden, oder die Funktion mit true verlassen.



  • Und du solltest die ganzen Magic Numbers, wie 23 und 36, aus deinem Code verbannen.
    Ein ein paar const könnten auch nicht schaden.



  • Hi(gh)!

    @th69 sagte in Rudimentärer Eingabe-Parser:

    Und du solltest die ganzen Magic Numbers, wie 23 und 36, aus deinem Code verbannen.
    Ein ein paar const könnten auch nicht schaden.

    Daran hatte ich auch schon gedacht... aber wie ermittle ich die Größe der ersten Dimension in einem mehrdimensionalen Array?

    Bis bald im Khyberspace!

    Yadgar



  • @yadgar sagte in Rudimentärer Eingabe-Parser:

    aber wie ermittle ich die Größe der ersten Dimension in einem mehrdimensionalen Array?

    Wozu?
    In C macht man #defines
    Oder enum oder const.

    Hauptsache die Zahl ist nur einmal im Code vorhanden.



  • Damit meine ich aber auch, daß man den beiden Funktionen die Größe des Arrays als Parameter mitgibt, ansonsten sind diese Funktionen ja viel zu spezialisiert und fehleranfällig (wenn z.b. das Array dann doch einmal vergrößert wird) - geschweige denn von Hand die Größe des Arrays ermitteln zu müssen...

    PS: Die Größe eines (vom Compiler generierten) Arrays ermittelt man ja mittels sizeof():

    int max_felder = sizeof(felder) / sizeof(felder[0]);
    


  • @th69 sagte in Rudimentärer Eingabe-Parser:

    Damit meine ich aber auch, daß man den beiden Funktionen die Größe des Arrays als Parameter mitgibt, ansonsten sind diese Funktionen ja viel zu spezialisiert und fehleranfällig (wenn z.b. das Array dann doch einmal vergrößert wird) - geschweige denn von Hand die Größe des Arrays ermitteln zu müssen...

    PS: Die Größe eines (vom Compiler generierten) Arrays ermittelt man ja mittels sizeof():

    int max_felder = sizeof(felder) / sizeof(felder[0]);
    

    Werden bei Arrays, die als char* name[] deklariert werden, die einzelnen Felder nicht nach aktuellem Bedarf unterschiedlich lang? Oder haben Goll, Grüner, Wieser mir da auch Kokolores erzählt?

    Bis bald im Khyberspace!

    Yadgar



  • Ja, und deswegen kannst du über diese Formel eben die Anzahl der enthaltenen Elemente ermitteln.

    Bei einem char*-Array liegen ja dann X Adresswerte (Zeiger) hintereinander, d.h. bei deinem Array mit 36 Einträgen wäre das Gesamtarray 36 * sizeof(char*) Bytes groß. Und daher wird durch sizeof(felder[0]) (= sizeof(char*)) dividiert.
    Selbst wenn du dann den Datentyp mal verändern solltest, so paßt dann immer noch die Formel.


Log in to reply