diff --git a/README.md b/README.md index ebed3d3..2e9a3f5 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,10 @@ I got bored with having to use complicated checking and stuff when working with 4. Getting and setting a value of a vector on a given index 5. Pushing a value at the end of a vector 6. Inserting a value into a vector at a given index +7. Insertion of a vector into another vector #### TODO: -1. Insertion of a vector into another vector - + You tell me @@ -42,4 +41,4 @@ I got bored with having to use complicated checking and stuff when working with #### Run demo -`make && ./demo` \ No newline at end of file +`make && ./demo` diff --git a/demo.c b/demo.c index 1484465..66afa12 100644 --- a/demo.c +++ b/demo.c @@ -4,91 +4,26 @@ #include int main(int argc, char **argv) { - printf("demonstration of the power of dynamically allocated arrays in c:\n-----------\n\n"); + vector_t *vv = vectorInit(VECTOR); + vector_t *fv = vectorInit(FLOAT); + vectorPrint(vv); - printf("initializing an integer vector\n"); - vector_t *v = vectorInit(INT); + vectorPush(fv, &(float){3.14}); + vectorPush(fv, &(float){5.123}); - printf("vector after initialization\n"); - vectorPrint(v); + vectorPush(vv, fv); + vectorPush(vv, fv); + vectorPush(vv, fv); - printf("pushing an element of value 1 into vector\n"); - int element = 1; - vectorPush(v, &element); - vectorPrint(v); + vectorPush(fv, &(float){156.1}); + vectorPush(fv, &(float){6.124}); - printf("pushing another element (value 2) into vector\n"); - element = 2; - vectorPush(v, &element); - vectorPrint(v); + vectorInsertAt(vv, 1, fv); - printf("inserting 3 at index 1\n"); - element = 3; - vectorInsertAt(v, 1, &element); - vectorPrint(v); - - printf("popping the last value from the vector\n"); - int popped = *((int *)vectorPop(v)); - printf("popped: %d\n", popped); - printf("vector after popping\n"); - vectorPrint(v); + vectorPrint(vv); - printf("initializing a second vector of type vector_t (multidimensional vector => vector of vectors)\n"); - vector_t *w = vectorInit(VECTOR); - - printf("vector after initialization\n"); - vectorPrint(w); - - printf("pushing the first vector into the newly created one\n"); - vectorPush(w, v); - vectorPrint(w); - printf("once again\n"); - vectorPush(w, v); - vectorPrint(w); - printf("popping\n"); - vector_t *poppedv = (vector_t *)vectorPop(w); - printf("popped vector\n"); - vectorPrint(poppedv); - printf("vector from which was popped after pop\n"); - vectorPrint(w); - - printf("initializing a char vector (variable-length string) with value \"Hello, world!\"\n"); - vector_t *charVector = vectorInit(CHAR); - char *word = "Hello, world!"; - for (int i = 0; i < strlen(word); i++) { - vectorPush(charVector, &word[i]); - } - printf("char vector as string\n"); - vectorPrintAsString(charVector); - - printf("char vector converted into a regular string\n"); - char *newWord = vectorToString(charVector); - printf("new word: %s\n", newWord); - - printf("setting a value in the char vector on index 10 to \"\" (nothing, effectively deleting the character, although the size of the vector stays the same!)\n"); - vectorSetAt(charVector, 10, ""); // should change the vector to "Hello, word!" (size stays the same!) - vectorPrintAsString(charVector); - - printf("files section\n---------------\n"); - printf("initializing a file called test.txt with mode \"r\" (reading it)\n"); - file_t* f = fileInit("test.txt", "r"); - - printf("printing the file contents\n"); - filePrint(f); - printf("file length (line count): %d\n", f->length); - printf("file as vector\n"); - vectorPrint(f->lines); - printf("file to string\n"); - char* strFile = fileToString(f); - printf("%s", strFile); - - printf("cleaning up vectors\n"); - vectorCleanup(v); - vectorCleanup(w); - vectorCleanup(charVector); - - printf("cleaning up files\n"); - fileCleanup(f); + vectorCleanup(vv); + vectorCleanup(fv); return 0; } diff --git a/src/vector.c b/src/vector.c index 4fe38b3..3504845 100644 --- a/src/vector.c +++ b/src/vector.c @@ -5,17 +5,17 @@ void vectorCleanup(vector_t* v) { - free(v->data); - free(v); + free(v->data); + free(v); } int printNewline = 0; void vectorReset(vector_t* v) { - while (v->size > 0) { - vectorPop(v); - } + while (v->size > 0) { + vectorPop(v); + } } void @@ -95,16 +95,16 @@ _printVectorAsStringRecursive(vector_t* v, int depth) { int i; for (i = 0; i < v->size; i++) { switch (v->type) { - case CHAR: - fprintf(stdout, "%c", *((char *)(v->data) + i)); - break; - case VECTOR: - // Recursively print each level of the vector - _printVectorAsStringRecursive((vector_t *)(v->data + i * v->elementSize), depth + 1); - break; - default: - perror("tried to print a non-char type vector as string\n"); - exit(EXIT_FAILURE); + case CHAR: + fprintf(stdout, "%c", *((char *)(v->data) + i)); + break; + case VECTOR: + // Recursively print each level of the vector + _printVectorAsStringRecursive((vector_t *)(v->data + i * v->elementSize), depth + 1); + break; + default: + perror("tried to print a non-char type vector as string\n"); + exit(EXIT_FAILURE); } } if (depth != 0) fprintf(stdout, "\n"); // do not print the last additional new line @@ -113,18 +113,18 @@ _printVectorAsStringRecursive(vector_t* v, int depth) { void vectorPrintAsString(vector_t* v) { switch (v->type) { - case CHAR: - for (int i = 0; i < v->size; i++) { - fprintf(stdout, "%c", *((char *)(v->data) + i)); - } - fprintf(stdout, "\n"); - break; - case VECTOR: - _printVectorAsStringRecursive(v, 0); - break; - default: - perror("tried to print a non-char type vector as string\n"); - exit(EXIT_FAILURE); + case CHAR: + for (int i = 0; i < v->size; i++) { + fprintf(stdout, "%c", *((char *)(v->data) + i)); + } + fprintf(stdout, "\n"); + break; + case VECTOR: + _printVectorAsStringRecursive(v, 0); + break; + default: + perror("tried to print a non-char type vector as string\n"); + exit(EXIT_FAILURE); } } @@ -150,8 +150,8 @@ vectorInit(dataType_e type) { v->elementSize = sizeof(char); break; case VECTOR: - v->elementSize = sizeof(vector_t); - break; + v->elementSize = sizeof(vector_t); + break; default: perror("specify a valid vector type\n"); exit(EXIT_FAILURE); @@ -169,36 +169,36 @@ vectorInit(dataType_e type) { void vectorPush(vector_t* v, void* element) { switch (v->type) { - case INT: - *((int *)(v->data) + v->size) = *((int *)element); - break; - case FLOAT: - *((float *)(v->data) + v->size) = *((float *)element); - break; - case CHAR: - *((char *)(v->data) + v->size) = *((char *)element); - break; - case VECTOR: - // Instead of reallocating memory for vector_t pointers, allocate memory for the vector data - if (v->size == 0) { - // Allocate memory for the vector data for the first time - v->data = malloc(v->elementSize * v->capacity); - } else { - // Reallocate memory for the vector data - v->data = realloc(v->data, v->elementSize * v->capacity); - } - if (v->data == NULL) { - perror("failed to allocate memory for vector data\n"); + case INT: + *((int *)(v->data) + v->size) = *((int *)element); + break; + case FLOAT: + *((float *)(v->data) + v->size) = *((float *)element); + break; + case CHAR: + *((char *)(v->data) + v->size) = *((char *)element); + break; + case VECTOR: + // Instead of reallocating memory for vector_t pointers, allocate memory for the vector data + if (v->size == 0) { + // Allocate memory for the vector data for the first time + v->data = malloc(v->elementSize * v->capacity); + } else { + // Reallocate memory for the vector data + v->data = realloc(v->data, v->elementSize * v->capacity); + } + if (v->data == NULL) { + perror("failed to allocate memory for vector data\n"); + exit(EXIT_FAILURE); + } + + // Copy the vector data from the element to the vector + memcpy((vector_t *)(v->data) + v->size, (vector_t *)element, sizeof(vector_t)); + + break; + default: + perror("specify a valid vector type\n"); exit(EXIT_FAILURE); - } - - // Copy the vector data from the element to the vector - memcpy((vector_t *)(v->data) + v->size, (vector_t *)element, sizeof(vector_t)); - - break; - default: - perror("specify a valid vector type\n"); - exit(EXIT_FAILURE); } v->size += 1; @@ -209,41 +209,41 @@ vectorPush(vector_t* v, void* element) { void* vectorPop(vector_t* v) { - // capacity is always a power of 2, so a rounding error cannot happen i guess _/-(shi)-\_ - - switch (v->type) { - case INT: - int *iretval = (int *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - v->data = realloc(v->data, v->elementSize * v->capacity); - if (v->capacity == 0) v->capacity = 1; - return iretval; - case FLOAT: - float *fretval = (float *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - v->data = realloc(v->data, v->elementSize * v->capacity); - return fretval; - case CHAR: - char *cretval = (char *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - v->data = realloc(v->data, v->elementSize * v->capacity); - return cretval; - case VECTOR: - vector_t *vretval = (vector_t *)(v->data) + v->size-1; - v->size -= 1; - if (v->size <= v->capacity / 2) v->capacity /= 2; - if (v->capacity == 0) v->capacity = 1; - v->data = realloc(v->data, v->elementSize * v->capacity); - return vretval; - default: - perror("specify a valid vector type\n"); - exit(EXIT_FAILURE); - } + // capacity is always a power of 2, so a rounding error cannot happen i guess _/-(shi)-\_ + + switch (v->type) { + case INT: + int *iretval = (int *)(v->data) + v->size-1; + v->size -= 1; + if (v->size <= v->capacity / 2) v->capacity /= 2; + v->data = realloc(v->data, v->elementSize * v->capacity); + if (v->capacity == 0) v->capacity = 1; + return iretval; + case FLOAT: + float *fretval = (float *)(v->data) + v->size-1; + v->size -= 1; + if (v->size <= v->capacity / 2) v->capacity /= 2; + if (v->capacity == 0) v->capacity = 1; + v->data = realloc(v->data, v->elementSize * v->capacity); + return fretval; + case CHAR: + char *cretval = (char *)(v->data) + v->size-1; + v->size -= 1; + if (v->size <= v->capacity / 2) v->capacity /= 2; + if (v->capacity == 0) v->capacity = 1; + v->data = realloc(v->data, v->elementSize * v->capacity); + return cretval; + case VECTOR: + vector_t *vretval = (vector_t *)(v->data) + v->size-1; + v->size -= 1; + if (v->size <= v->capacity / 2) v->capacity /= 2; + if (v->capacity == 0) v->capacity = 1; + v->data = realloc(v->data, v->elementSize * v->capacity); + return vretval; + default: + perror("specify a valid vector type\n"); + exit(EXIT_FAILURE); + } } char* @@ -299,89 +299,89 @@ vectorToString(vector_t* v) { void* vectorGetAt(vector_t* v, int index) { - switch (v->type) { - case INT: - return (int *)(v->data) + index; - case FLOAT: - return (float *)(v->data) + index; - case CHAR: - return (char *)(v->data) + index; - case VECTOR: - return (vector_t *)(v->data) + index; - default: - perror("specify a valid vector type\n"); - exit(EXIT_FAILURE); - } + switch (v->type) { + case INT: + return (int *)(v->data) + index; + case FLOAT: + return (float *)(v->data) + index; + case CHAR: + return (char *)(v->data) + index; + case VECTOR: + return (vector_t *)(v->data) + index; + default: + perror("specify a valid vector type\n"); + exit(EXIT_FAILURE); + } } void vectorSetAt(vector_t* v, int index, void* element) { - if (index >= v->size) { - perror("index out of range\n"); - exit(EXIT_FAILURE); - } + if (index >= v->size) { + perror("index out of range\n"); + exit(EXIT_FAILURE); + } - switch (v->type) { - case INT: - *((int *)(v->data) + index) = *((int *)element); - break; - case FLOAT: - *((float *)(v->data) + index) = *((float *)element); - break; - case CHAR: - *((char *)(v->data) + index) = *((char *)element); - break; - case VECTOR: - *((vector_t *)(v->data) + index) = *((vector_t *)element); - break; - default: - perror("specify a valid vector type\n"); - exit(EXIT_FAILURE); - } + switch (v->type) { + case INT: + *((int *)(v->data) + index) = *((int *)element); + break; + case FLOAT: + *((float *)(v->data) + index) = *((float *)element); + break; + case CHAR: + *((char *)(v->data) + index) = *((char *)element); + break; + case VECTOR: + *((vector_t *)(v->data) + index) = *((vector_t *)element); + break; + default: + perror("specify a valid vector type\n"); + exit(EXIT_FAILURE); + } } void vectorInsertAt(vector_t* v, int index, void* element) { - if (index >= v->size) { - perror("index out of range\n"); - exit(EXIT_FAILURE); - } + if (index >= v->size) { + perror("index out of range\n"); + exit(EXIT_FAILURE); + } - v->size += 1; - if (v->size >= v->capacity) { - v->capacity *= 2; - v->data = realloc(v->data, v->elementSize * v->capacity); - } + v->size += 1; + if (v->size >= v->capacity) { + v->capacity *= 2; + v->data = realloc(v->data, v->elementSize * v->capacity); + } - switch (v->type) { - case INT: - // move all elements to the right by one - for (int i = v->size-1; i > index; i--) { - *((int *)(v->data) + i) = *((int *)(v->data) + i-1); - } - // set the element at the given index - *((int *)(v->data) + index) = *((int *)element); - break; - case FLOAT: - for (int i = v->size-1; i > index; i--) { - *((float *)(v->data) + i) = *((float *)(v->data) + i-1); - } - *((float *)(v->data) + index) = *((float *)element); - break; - case CHAR: - for (int i = v->size-1; i > index; i--) { - *((char *)(v->data) + i) = *((char *)(v->data) + i-1); - } - *((char *)(v->data) + index) = *((char *)element); - break; - case VECTOR: - for (int i = v->size-1; i > index; i--) { - *((vector_t *)(v->data) + i) = *((vector_t *)(v->data) + i-1); - } - *((vector_t *)(v->data) + index) = *((vector_t *)element); - break; - default: - perror("specify a valid vector type\n"); - exit(EXIT_FAILURE); - } + switch (v->type) { + case INT: + // move all elements to the right by one + for (int i = v->size-1; i > index; i--) { + *((int *)(v->data) + i) = *((int *)(v->data) + i-1); + } + // set the element at the given index + *((int *)(v->data) + index) = *((int *)element); + break; + case FLOAT: + for (int i = v->size-1; i > index; i--) { + *((float *)(v->data) + i) = *((float *)(v->data) + i-1); + } + *((float *)(v->data) + index) = *((float *)element); + break; + case CHAR: + for (int i = v->size-1; i > index; i--) { + *((char *)(v->data) + i) = *((char *)(v->data) + i-1); + } + *((char *)(v->data) + index) = *((char *)element); + break; + case VECTOR: + for (int i = v->size-1; i > index; i--) { + *((vector_t *)(v->data) + i) = *((vector_t *)(v->data) + i-1); + } + *((vector_t *)(v->data) + index) = *((vector_t *)element); + break; + default: + perror("specify a valid vector type\n"); + exit(EXIT_FAILURE); + } }