Forum: Compiler & IDEs argv - Elemente abspeichern


von Le X. (lex_91)


Lesenswert?

Hallo,

ich schreibe gerade einen kleinen Parser.
Dieser soll eine Datei anhand bestimmter Token (die als C-String 
vorliegen) untersuchen.

Das Programm läuft soweit.
Momentan liegen diese Kriterien alle hartkodiert in einem Array der 
Form:
char *tokens[] = {
    "token1",
    "token2"
    ...
};

Nun möchte ich gerne die Tokens von der Kommandozeile übernehmen.
argv zu parsen ist soweit kein Problem. Einige Optionen sind auch 
bereits implementiert.

Allerdings muss ich, wenn ein Element von argv als Token identifiziert 
habe, dieses dynamisch meinem Token-Array hinzufügen.
(Oder eben einen Zeiger darauf, bsp: tokens[x] = argv[y];)

Spontan wüsst ich keinen eleganten Ansatz, außer irgendwelche 
realloc-Orgien.

Am einfachsten ist es wohl, wenn ich den Speicher für mein Array 
statisch reserviere (und eine MAX_TOKEN_COUNT definiere).
Da ich ja nur Zeiger in meinem Array habe sollte der verschenkte 
Speicher ja nicht ins Gewicht fallen.

Weiß vielleicht jemand von euch eine simple (dynamsiche) Lösung?
Auch wenn man den Speicherverbrauch von ein paar char-Zeigern nicht 
merkt finde ich sowas unschön, und würd auch gerne für die Zukunft 
wissen wie man das besser löst.

Gruß,
lex

von Karl H. (kbuchegg)


Lesenswert?

le x. schrieb:

> Weiß vielleicht jemand von euch eine simple (dynamsiche) Lösung?
> Auch wenn man den Speicherverbrauch von ein paar char-Zeigern nicht
> merkt finde ich sowas unschön, und würd auch gerne für die Zukunft
> wissen wie man das besser löst.

Du kennst doch im Vorfeld die Anzahl der Argumente. argc verrät dir das. 
mittels argc ein Array allokieren und gut ists.

Ansonsten dann eben in deinem Fall mit einem einfachen Array einfach 
realloc benutzen. So schlimm ist das auch wieder nicht.

von Le X. (lex_91)


Lesenswert?

Naja ich hab ja auch noch andere Argumente (Optionen), die übergeben 
werden.

Grundsätzlich kann ich den bissl Speicher für die Zeiger schon 
entbehren.
Aber vielleicht gibts ja ne Musterlösung...

von Karl H. (kbuchegg)


Lesenswert?

le x. schrieb:
> Naja ich hab ja auch noch andere Argumente (Optionen), die übergeben
> werden.

ok.

>
> Grundsätzlich kann ich den bissl Speicher für die Zeiger schon
> entbehren.
> Aber vielleicht gibts ja ne Musterlösung...

3 Möglichkeiten.

* vorher die Argumente durchgehen und abzählen, wieviele Token da dabei
  sind. Array entsprechend allokieren und erst dann die Command Line
  auswerten

* das Array sukzessive mittels realloc um 1 vergrößern

* eine Speicherverwaltung ala 'lineare Liste' aufbauen, was deswegen
  einfach ist, weil normale C-Programmierer das in Form von fertigem
  Code in ihrem Vorrat rumliegen haben.


Es gibt nur die beiden prinzipiellen Möglichkeiten: Entweder man weiß im 
Vorfeld wieviel Speicher man braucht oder man allokiert den Speicher 
beim Durchmarsch. Wobei letzteres in das weite Gebiet der dynamischen 
Datenstrukturen führt (führen kann). realloc ist ja nur die (fade) 
Spitze des Eisbergs.

von Le X. (lex_91)


Lesenswert?

Ich werd einfach die Liste durchgehen um zu wissen, wieviele Elemente es 
werden, dann den Speicher allokieren und dann argv nochmal durchgehen, 
diesesmal mit "richtigem" parsen.

Meine Dateien haben tausende von Zeilen, da fällt es nicht ins Gewicht, 
argv zweimal durchzugehen :-)

Danke!

von Peter II (Gast)


Lesenswert?

le x. schrieb:
> Ich werd einfach die Liste durchgehen um zu wissen, wieviele Elemente es
> werden, dann den Speicher allokieren und dann argv nochmal durchgehen,
> diesesmal mit "richtigem" parsen.

naja ob das nun schöner ist, als gleich ein array mit der anzahl von 
argv elementen anzulegen (auch wenn dann ein paar byte frei bleiben) ist 
fragwürdig.

je nach BS und lib wird der speicher eh aufgerundet.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> le x. schrieb:
>> Ich werd einfach die Liste durchgehen um zu wissen, wieviele Elemente es
>> werden, dann den Speicher allokieren und dann argv nochmal durchgehen,
>> diesesmal mit "richtigem" parsen.
>
> naja ob das nun schöner ist, als gleich ein array mit der anzahl von
> argv elementen anzulegen (auch wenn dann ein paar byte frei bleiben) ist
> fragwürdig.

Würd ich ehrlich gesagt in diesem Fall auch machen. Zumal ja so eine 
Command Line auch nicht unendlich lang ist.


Aber was spricht den gegen realloc()? Das hab ich immer noch nicht 
verstanden. Ist doch trivial
1
  char** arvPtr = argv;
2
3
  int tokenCnt = 0;
4
  char** tokenPtr = NULL;
5
6
  while( *argvPtr ) {
7
8
 
9
    ....
10
    {
11
      // Token merken
12
      tokenCnt++;
13
      newTokenPtr = realloc( tokenPtr, sizeof( char* ) * tokenCnt );
14
      if( newTokenPtr == NULL ) {
15
        printf( "Out of memory while allocating tokens\n" );
16
        free( tokenPtr );
17
        exit( EXIT_FAILURE );
18
      }
19
      tokenPtr = newTokenPtr;
20
      tokenPtr[tokenCnt-1] = *argvPtr;
21
    }
22
23
    argvPtr++;
24
25
  }



Ich seh da jetzt nicht, wo da das große Problem liegt.
OK, ein bischen Laufzeit zu Beginn des Programms. Aber wenn das Pgm dann 
sowieso 3 Minuten rumrödelt, sind die 2 Zehntelsekunden auch schon 
wurscht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.