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
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.
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...
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.
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!
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.