T
Nachfolgende Variante eines Tokenizer ersetzt alle spaces in buffer durch 0 und trägt die Anfangsadressen von jedem Token in buffer in die Token List ein.
#include <assert.h>
#include <ctype.h> // isspace
#include <stdio.h> // NULL
struct TokenInfo {
char* token;
};
// Returns a pointer to the last token + 1
TokenInfo* Tokenize(char* buffer, TokenInfo* token_list) {
assert(buffer != NULL);
assert(token_list != NULL);
bool found_token = false;
for (char* current = buffer; *current != 0; ++current) {
if (found_token) {
if (isspace(*current)) {
*current = 0;
found_token = false;
}
} else {
if (isspace(*current)) {
*current = 0;
} else {
token_list++->token = current;
found_token = true;
}
}
} // for
return token_list;
}
Die Interaktion in der Konsole oder einer Pipe sieht dann ihn etwa wie folgt aus:
#include <stdio.h> // fgets, stdin, NULL
void Parse() {
char buffer[1024];
while (fgets(buffer, 1024, stdin) != NULL) {
TokenInfo token_list[1024]; // HACK
TokenInfo* end = Tokenize(buffer, token_list);
for (TokenInfo* current = token_list; current < end; ++current) {
const char* token = current->token;
// Do something with "token"
}
} // while
// End-of-file or error
}
Der Datentyp TokenInfo soll nur verhindern, dass man direkt mit Doppelzeigern arbeiten muss (tut man so zwar auch, aber nicht so offensichtlich).
Im Grunde ist dieser Algorithmus einen Ticken weniger performant als der Vorgänger, da man zusätzlich noch eine Token List benötigt.