[C] 문자열 유사클래스 구현
oop 흉내.
C의 한계로, 메서드마다 첫번째 인자로 객체 자신의 주소를 보내줘야 함.
https://github.com/myyrakle/c-oop-string/blob/master/main.c
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 | #include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdarg.h> //기본 초기화 목록입니다.//기본 빈 값을 넣어주고,//유사 멤버함수들을 전부 넣어줍니다.#define NullString { \NULL, 0, _string_set, _string_setn, _string_gets, _string_get_length, _string_copy_from, _string_clone, _string_move, _string_append, _string_append_raw, _string_swap, _string_clear, _string_is_empty, _string_compare, _string_compare_raw, _string_is_same, _string_is_same_raw, _string_format, _string_append_format, _string_at, _string_ptr_at, _string_findc, _string_finds, _string_finds_raw, } //C스타일 문자열 유사클래스입니다.struct String{ char* data; size_t length; //문자열을 할당합니다. void (set)(struct String, const char*); void (setn)(struct String, const char*, size_t); //문자열을 가져옵니다. const char* (gets)(const struct String); //문자열의 길이를 가져옵니다. size_t (get_length)(const struct String); //깊은복사를 행합니다. void (copy_from)(struct String, const struct String*); //깊게 복제된 객체를 반환합니다. struct String (clone)(const struct String); //이동합니다. 자신은 clear가 됩니다. struct String (move)(struct String); //이어붙입니다. void (append)(struct String, const struct String*); //String 버전입니다. void (append_raw)(struct String, const char*); //생 문자열 버전입니다. //교환합니다. void (swap)(struct String, struct String*); //지워버립니다. void (clear)(struct String); //비어있는지 여부를 확인합니다. int (is_empty)(const struct String); //비교해서 같으면 0... 뭐 그런거요 int (compare)(const struct String, const struct String*); //String 버전입니다. int (compare_raw)(const struct String, const char*); //생 문자열 버전입니다. //같으면 1. 다르면 0. int (is_same)(const struct String, const struct String*); //String 버전입니다. int (is_same_raw)(const struct String, const char*); //생 문자열 버전입니다. //포맷팅합니다. void (format)(struct String, const char*, ...); //포맷팅해서 그대로 대입합니다. void (append_format)(struct String, const char*, ...); //포맷팅한 문자열을 이어붙입니다. //인덱싱합니다. 범위를 벗어나면 EOF를 줘요. int (at)(const struct String, size_t); //그냥 그 문자를 반환합니다. int* (ptr_at)(struct String, size_t); //그 문자의 주소를 반환합니다. //문자나 문자열을 탐색해서 인덱스를 줍니다. //못찾으면 EOF를 반환합니다. int (findc)(const struct String, char c); //문자를 찾습니다. int (finds)(const struct String, const struct String*); //String 문자열을 찾습니다. int (finds_raw)(const struct String, const char*); //생 문자열을 받아서 찾습니다.};typedef struct String String;typedef String string; /아아.. 이것은... [선언]이라고 하는 것이다.../String make_string(const char*);String make_nullstring();/이것은... [유사 메서드]라고 하는 것이지../void _string_set(String*, const char*);void _string_setn(String*, const char*, size_t);const char* _string_gets(const String*);size_t _string_get_length(const String*);void _string_copy_from(String* self, const String* other);String _string_clone(const String* self);String _string_move(String* self);void _string_append(String* self, const String* other);void _string_append_raw(String* self, const char* other);void _string_swap(String* self, String* other);void _string_clear(String* self);int _string_is_empty(const String* self);int _string_compare(const String* self, const String* other);int _string_compare_raw(const String* self, const char* other);int _string_is_same(const String* self, const String* other);int _string_is_same_raw(const String* self, const char* other);void _string_format(String* self, const char* format,...);void _string_append_format(String* self, const char* format, ...);int _string_at(const String* self, size_t index);int _string_ptr_at(String* self, size_t index);int _string_findc(const String* self, char c);int _string_finds(const String* self, const String* key);int _string_finds_raw(const String* self, const char* key); /이제... [정의]의 시간이 도래했노라.../void _string_set(String* self, const char* s){ self->length = strlen(s); free(self->data); //혹시 모르니까 self->data = malloc(sizeof(char)self->length +1); strncpy(self->data, s, self->length+1);} void _string_setn(String self, const char* s, size_t len){ self->length = len; free(self->data); self->data = malloc(sizeof(char)self->length +1); strncpy(self->data, s, self->length +1);} const char _string_gets(const String* self){ return self->data;} size_t _string_get_length(const String* self){ return self->length;} void _string_copy_from(String* self, const String* other){ self->length = other->length; free(self->data); self->data = malloc(sizeof(char)self->length +1); strncpy(self->data, other->data, self->length +1);} String _string_clone(const String self){ String temp = make_nullstring(); temp.setn(&temp, self->data, self->length); return temp;} String _string_move(String* self){ String temp = make_nullstring(); temp.data = self->data; temp.length = self->length; self->data=NULL; self->length=0; return temp;} void _string_append(String* self, const String* other){ self->length+=other->length; realloc(self->data, self->length+1); strncat(self->data, other->data, self->length+1);} void _string_append_raw(String* self, const char* other){ self->length+=strlen(other); realloc(self->data, self->length); strncat(self->data, other, self->length+1);} void _string_swap(String* self, String* other){ char* t = self->data; size_t t2 = self->length; self->data = other->data; self->length = other->length; other->data = t; other->length = t2;} void _string_clear(String* self){ self->length=0; free(self->data); self->data=NULL;} int _string_is_empty(const String* self){ return self->data==NULL;} int _string_compare(const String* self, const String* other){ return strcmp(self->data, other->data);}int _string_compare_raw(const String* self, const char* other){ return strcmp(self->data, other);} int _string_is_same(const String* self, const String* other){ return strcmp(self->data, other->data)==0;}int _string_is_same_raw(const String* self, const char* other){ return strcmp(self->data, other)==0;} enum{ STRING_BUFFER_SIZE = 200}; void _string_format(String* self, const char* format,...){ char buffer[STRING_BUFFER_SIZE]; va_list args; va_start(args, format); vsprintf(buffer, format, args); self->set(&self, buffer); va_end(args);} void _string_append_format(String* self, const char* format, ...){ char buffer[STRING_BUFFER_SIZE]; va_list args; va_start(args, format); vsprintf(buffer, format, args); self->append_raw(&self, buffer); va_end(args);} int _string_at(const String* self, size_t index){ if(index<0 || index>=self->length) return EOF; else return self->data[index];} int _string_ptr_at(String* self, size_t index){ if(index<0 || index>=self->length) return EOF; else return &(self->data[index]);} int _string_findc(const String* self, char c){ for(int i=0; i