Das ist ne ganz schöne Umkopiererer.
Du sagtest, dass deine Routinen ein argc/argv Handling
haben, woraufhin ich darauf hingewiesen habe, dass argv
kein 2D Array sondern ein Array von Pointern darstellt.
Der Unterschied ist: Deine Lösung sieht im Speicher
so aus:
command
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
während die argv Lösung so aussieht:
argv
+-----+ +---+---+---+
| o--------->| | |\0 |
+-----+ +---+---+---+ +---+---+---+---+
| o------------------------------->| | | |\0 |
+-----+ +---+---+---+---+ +---+---+---+---+
| o--------->| | | |\0 |
+-----+ +---+---+---+---+ +---+---+
| o------------------------------->| |\0 |
+-----+ +---+---+---+ +---+---+
| o--------->| | |\0 |
+-----+ +---+---+---+ +---+---+---+
| o------------------------------->| | |\0 |
+-----+ +---+---+---+---+ +---+---+---+
| o--------->| | | |\0 |
+-----+ +---+---+---+---+
|NULL |
+-----+
Nun sagt aber niemand, dass die Arrayfetzelchen rechts
alle unterschiedliche Arrays sein müssen. Die Pointer
können durchaus alle in dasselbe Array zeigen (die
aufgerufene Funktion, main(), hat sowieso kein Recht
im argv irgendwelche Manipulationen durchzuführen):
+---+---+---+---+---+---+---+---+---+---+---+---+
| | |\0 | |\0 | | | \0| | |\0 | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^ ^ ^ ^
+-----+ | | | |
| o--------+ | | |
+-----+ | | |
| o--------------------+ | |
+-----+ | |
| o----------------------------+ |
+-----+ |
| o----------------------------------------+
+-----+
|NULL |
+-----+
Hintergrund der ganzen Storry: Dieses grosse Array hast du ja
bereits. Es ist dein 'Zeile' Array. Alles was du noch tun musst
um ein argv zu implementieren ist ein Array von Pointern
aufzusetzen, welche in dieses Array hineinzeigen. Und natürlich
müssen im 'Zeile' Array noch die \0 eingefügt werden um die
jeweiligen String Enden zu markieren.
Zum Aufsetzen des Arrays kommt jetzt strtok() ins Spiel.
Es zeigt sich, dass strtok() eine dafür perfekt passende Aktion
macht:
* strtok() sucht nach dem ersten Zeichen, welches nicht als Trenn-
zeichen angegeben wurde. Diese Position wird als Pointer
retourniert und markiert den Beginn des Tokens
* strtok() sucht nach dem Ende des Tokens, indem es solange den
String weiterliest, bis eines der Trennzeichen auftaucht.
Dieses Zeichen wird durch ein '\0' Zeichen ersetzt.
* strtok() liefert NULL wenn es keinen Token mehr identifizieren
konnte.
(ungetesteter Code)
1 | const char* argv[max_command];
|
2 | int argc;
|
3 |
|
4 | ...
|
5 |
|
6 | argc = 0;
|
7 | char* Token = strtok( zeile, " \t" );
|
8 |
|
9 | while( Token != NULL && argc < max_command - 1) {
|
10 | argv[argc++] = Token;
|
11 | Token = strtok( NULL, " \t" );
|
12 | }
|
13 | argv[argc] = NULL;
|
14 |
|
15 | ...
|
16 | //
|
17 | // und damit kann dann eine Funktion aufgerufen werden
|
18 | //
|
19 | foo( argc, argv );
|