#include #include #include /* listsplit.c, (C) Hauke Lubenow, 2017, License: LGPL. */ typedef char * string; typedef char * stringpointer; enum types {TYPE_VOID, TYPE_INT, TYPE_FLOAT, TYPE_CHAR, TYPE_STRING}; struct List { struct List *next; struct List *previous; int type; void *data; }; typedef struct List List; // ---------------------------------------------- // List-functions: List *initList() { List *border_first = malloc(sizeof(List)); List *border_last = malloc(sizeof(List)); border_first->next = border_last; border_first->previous = NULL; border_last->previous = border_first; border_last->next = NULL; border_first->type = TYPE_VOID; border_last->type = TYPE_VOID; return border_first; } void push(List *current, void *data, int type) { while (current->next != NULL) { current = current->next; } List *border_last = current; current = current->previous; List *sn = malloc(sizeof(List)); sn->type = type; if (type == TYPE_STRING) { sn->data = strdup((char *) data); } else { sn->data = data; } border_last->previous = sn; current->next = sn; sn->next = border_last; sn->previous = current; } string getNodeDataAsString(List *current) { string s = malloc(100); switch (current->type) { case TYPE_VOID: puts("Warning: Accessing data of border-node."); s = ""; break; case TYPE_INT: sprintf(s, "%d", * (int *) current->data); break; case TYPE_FLOAT: sprintf(s, "%f", * (double *) current->data); break; case TYPE_CHAR: sprintf(s, "\'%c\'", * (char *) current->data); break; case TYPE_STRING: s = realloc(s, strlen(current->data) + 10); sprintf(s, "\"%s\"", (char *) current->data); break; } return s; } void printList(List *current) { char *s; if (current->previous == NULL) { current = current->next; } printf("["); while (current->next != NULL) { s = getNodeDataAsString(current); printf("%s", s); free(s); current = current->next; if (current->next != NULL) { printf(", "); } } // Now, we're on border_last: printf("]\n"); } void clearList(List *current) { while (current->next != NULL) { current = current->next; if (current->previous->type == TYPE_STRING) { free(current->previous->data); } free(current->previous); } free(current); } // ---------------------------------------------- // Functions, that use strings and lists: List *split(string s, string substr, int showlast) { List *l = initList(); stringpointer p = s; int slen = strlen(s); stringpointer p2 = s; string a; int i; while ((p = strstr(p, substr)) != NULL){ a = malloc(p - p2); for (i = 0; i < p - p2; i++) { *(a + i) = *(p2 + i); } *(a + i) = '\0'; push(l, a, TYPE_STRING); free(a); p += strlen(substr); p2 = p; } // The last part of the string, after the last occurrence // of substr has been found: if (p2 - s < slen) { push(l, p2, TYPE_STRING); } else if (p2 - s == slen && showlast) { push(l, p2, TYPE_STRING); } free(s); return l; } int main() { string a = malloc(100); strcpy(a, "The black cat climbed the green tree"); List *l = initList(); l = split(a, " ", 0); printList(l); clearList(l); return 0; }