Frage

Was ist der beste Ansatz, um zu definieren, zusätzliche Daten für typedef Enumerationen in C?

Beispiel:

typedef enum {
  kVizsla = 0,
  kTerrier = 3,
  kYellowLab = 10
} DogType;

Nun würde ich gerne definieren Sie Namen für die einzelnen, zum Beispiel kVizsla sollte "vizsla".Ich verwende derzeit eine Funktion, die eine Zeichenfolge zurückgibt, die mit eine große switch-block.

War es hilfreich?

Lösung

@dmckee:Ich denke, dass die vorgeschlagene Lösung ist gut, aber für einfache Daten (z.B.wenn nur der name ist notwendig), es könnte erweitert werden, mit der automatisch generierten code.Während es viele Möglichkeiten zur automatischen Generierung von code, für etwas so einfaches wie das ich glaube, Sie könnten schreiben einen einfachen XSLT, nimmt in eine XML-Darstellung der enum-und Ausgänge der code-Datei.

Die XML würde von der form:

<EnumsDefinition>
    <Enum name="DogType">
        <Value name="Vizsla" value="0" />
        <Value name="Terrier" value="3" />
        <Value name="YellowLab" value="10" />
    </Enum>
</EnumsDefinition>

und der resultierende code wäre etwas ähnliches wie das, was dmckee vorgeschlagen, in seine Lösung.

Für Informationen, wie zu schreiben, wie ein XSLT-versuchen hier oder suchen Sie einfach es in google, und finden Sie ein tutorial, das passt.Schreiben von XSLT-nicht viel Spaß, IMO, aber es ist nicht schlecht, zumindest für relativ einfache Aufgaben wie diese.

Andere Tipps

Eine perfekte Passform für X () - Makros.Diese Arten von Makros können mit dem C-Präprozessor zu konstruieren, enums und arrays aus der gleichen Quelle.Sie müssen nur hinzufügen neue Daten zu der #define-mit dem X () - makro.

Ihr Beispiel kann wie folgt geschrieben werden:

// All dog data goes in this list
#define XDOGTYPE \
  X(kVizsla,0,"vizsla") \
  X(kTerrier,3,"terrier") \
  X(kYellowLab,10,"yellowlab")

 // Dog info
 typedef struct {
     int val;       // Defined value
     char * desc;   // Text description
 } DogType;

 // Build an array index using the Names
 typedef enum {
  #define X(Name,Val,Text)     Name,
   XDOGTYPE
  #undef X
  MAXDOGS
 } DogIndex;

 // Build a lookup table of values
 DogType Dog[] = {
  #define X(Name,Val,Text)    {Val,Text},
   XDOGTYPE
  #undef X
 };

 // Access the values
 for (i=0; i < MAXDOGS; i++)
    printf("%d: %s\n",Dog[i].val,Dog[i].desc);

Wenn Ihr die Enumerationswerte sind dicht genug ist, können Sie definieren ein array zu halten die Saiten und einfach nachgeschlagen werden (Verwendung von NULL für alle übersprungenen Wert und fügen Sie einen besonderen Fall handler auf Ihrem lookup-routine).

char *DogList[] = {
  "vizsla", /* element 0 */
  NULL,
  NULL,
  NULL,
  "terrier", /* element 3 */
  ...
};

Dies ist ineffizient für sparse-Enumerationen.

Auch wenn die Aufzählung ist nicht dicht, Sie können verwenden ein array von Strukturen zu halten der mapping.

typedef struct DogMaps {
  DogType index;
  char * name;
} DogMapt;
DogMapt DogMap[] = {
  {kVizsla, "vizsla"},
  {kTerrier, "terrier"},
  {kYellowLab, "yellow lab"},
  NULL
};

Der zweite Ansatz ist sehr flexibel, aber es bedeutet eine Suche durch die Zuordnung jedes mal, müssen Sie die Daten verwenden.Für große Datensätze betrachten Sie einen b-Baum oder hash anstelle eines Arrays.

Jede Methode kann verallgemeinert werden, um eine Verbindung zu mehr Daten.In der ersten verwenden Sie ein array von structs, in der zweiten nur mehr Mitglieder hinzufügen, zu der Struktur.

Sie, natürlich, wollen, schreiben verschiedene Handler zu vereinfachen Ihre Interaktion mit diesen Strukturen.


@Hershi mit allen Mitteln, eigenen code und Daten.Die oben genannten Beispiele sollen klar sein, eher als funktional.

Ich erröten zugeben, dass ich immer noch mit Leerzeichen getrennt, flat-files für diesen Zweck, sondern als die Art von strukturierten Eingang, die Sie zeigen, aber meine-Produktion-code Lesen würde, wie viel von den Daten aus externen Quellen wie möglich.


Warten Sie, ich sehe, dass Sie meinen code generation.

Sicher.Nichts falsch mit, dass.

Ich vermute allerdings, dass die OP war daran interessiert, was der generierte code sollte so Aussehen...

Das ist eine offene Frage, aber ein Vorschlag wäre die Verwendung einer Karte mit der enum als die Schlüssel geben und die zusätzlichen Informationen in den Wert.(Wenn Ihr Indizes sind kontinuierlich, im Gegensatz zu dem Beispiel, Sie verwenden können eine Sequenz container statt einer Karte).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top