#include #include #include #include struct string { char *data; size_t length; char own_data; }; void safe_free(struct string s){ if(s.own_data) free(s.data); } struct string make_string(char* data){ struct string new_string = {data, strlen(data), 0}; return new_string; } void print_string(struct string s){ write(1, s.data, s.length); write(1, "\n", 1); } void append(struct string *s, struct string addition){ if(s->own_data){ s->data = realloc(s->data, s->length + addition.length); } else { char *old_data = s->data; s->data = malloc(s->length + addition.length); memcpy(s->data, old_data, s->length); s->own_data = 1; } memcpy(s->data + s->length, addition.data, addition.length); s->length += addition.length; } struct string substr(const struct string original, size_t beginning, size_t end){ struct string substring; substring.data = original.data + beginning; substring.length = end - beginning; substring.own_data = 0; return substring; } char* c_substr(const char *original, size_t beginning, size_t end){ char* new_string = malloc(1 + end - beginning); memcpy(new_string, original + beginning, end - beginning); new_string[end - beginning] = 0; return new_string; } int main(){ /* Old way */ { char *our_string = "The slug went across the street in the middle of the night in the rain because there weren't any cars then."; char *slug = c_substr(our_string, 4, 9); printf("substring: %s\n", slug); printf("original: %s\n", our_string); free(slug); } /* With string "class" */ { struct string our_string = make_string("The slug went across the street in the middle of the night in the rain because there weren't any cars then."); struct string slug = substr(our_string, 4, 9); printf("substring, then original, with string \"class\"\n"); print_string(slug); print_string(our_string); append(&our_string, make_string(" The rain is good for their skin.")); print_string(our_string); append(&slug, make_string(" is a unit of mass in the english system, and a creature, and a type of shotgun ammunition")); print_string(slug); print_string(our_string); safe_free(our_string); safe_free(slug); } }