/// dynamic array class /// written by: Harry Irving #include #include #include #include typedef struct { int size; int capacity; char* data; } String; String str_with_capacity(int capacity) { String s; /// allocate memory for 'capacity' chars s.data = (char*)calloc(capacity, sizeof(char)); s.size = 0; s.capacity = capacity; return s; } String str_from_chars(char* string) { String s; s.data = (char*)calloc(strlen(string), sizeof(char)); strcpy(s.data, string); s.size = strlen(string); s.capacity = strlen(string); return s; } String str_from_slice(char* string, int len) { String s; s.data = (char*)calloc(len, sizeof(char)); strncpy(s.data, string, len); s.size = len; s.capacity = len; return s; } String str_new() { return str_with_capacity(1); } int str_dealloc(String* self) { free(self->data); return 0; } void str_push(String* self, char c) { // check size < capacity if (self->size < self->capacity) { self->data[self->size] = c; self->size++; return; } // reallocate to add capacity for an extra char int newcap = self->capacity + sizeof(char); self->data = (char*)realloc(self->data, newcap); self->data[self->size] = c; self->size++; self->capacity = newcap; return; } char str_pop(String* self) { if (self->size == 0) { return '\0'; } self->size--; char c = self->data[self->size]; return c; } void str_insert(String* self, int index, char c) { if (index > self->size) { return; } self->size++; for (int i = self->size - 1; i > index; i--) { self->data[i] = self->data[i - 1]; } self->data[index] = c; } void str_remove(String* self, int index) { if (index >= self->size) { return; } self->size--; for (int i = index; i < self->size; i++) { self->data[i] = self->data[i + 1]; } } String* str_lines(String* self, int* numlines) { char* string = self->data; String* lines = NULL; // find the number of lines in the file *numlines = 0; for (int i = 0; i < strlen(string); i++) { if (string[i] == '\n') { (*numlines)++; } } // add one if the last char is not a newline // in this case there is one more line than newline symbols if (self->data[strlen(self->data) - 1] != '\n') { (*numlines)++; } // allocate memory for an array of pointers to each line lines = (String*)malloc((*numlines + 1) * sizeof(String)); int i = 0; char* start = string; char* end = string; while (*end != '\0') { if (*end == '\n') { lines[i] = str_from_slice(start, end - start); end++; start = end; i++; } else { end++; } } // returns an array of String return lines; } /// splits a string into an array of strings based on a delimiter String* str_split(String* self, int* res_len, char c) { char* string = self->data; String* elements = NULL; // find the number of lines in the file bool flag = false; *res_len = 0; for (int i = 0; i < strlen(string); i++) { if (string[i] == c) { if (flag) { (*res_len)++; flag = false; } } else { flag = true; } } if (flag) { (*res_len)++; } // allocate memory for an array of pointers to each line elements = (String*)malloc((*res_len) * sizeof(String)); int i = 0; flag = false; char* start = string; char* end = string; while (*end != '\0') { if (*end == c) { if (flag) { elements[i] = str_from_slice(start, end - start); i++; } end++; start = end; flag = false; } else { end++; flag = true; } } if (flag) { elements[i] = str_from_slice(start, end - start); } // returns an array of String return elements; } int str_len(String* s) { return s->size; } char* to_chars(String* s) { return s->data; } // int main() { // String s = str_from_chars("hello\nworld\neeeee\notherline\n\0"); // int numlines = 0; // String* lns = str_lines(&s, &numlines); // str_dealloc(&s); // for (int i = 0; i < numlines; i++) { // printf("%s\n", lns[i].data); // str_dealloc(&lns[i]); // } // String s2 = str_from_chars("$this$needs$to$be$split"); // int elements = 0; // String* split = str_split(&s2, &elements, '$'); // str_dealloc(&s2); // printf("%d elements\n", elements); // for (int i = 0; i < elements; i++) { // printf("%s\n", split[i].data); // str_dealloc(&split[i]); // printf("(dealloced)\n"); // } // }