verified insertion of vectors into vectors; proved working

This commit is contained in:
Odweta
2023-12-21 11:35:28 +01:00
parent 3988892a5e
commit eb6b6c8343
3 changed files with 183 additions and 249 deletions
+2 -3
View File
@@ -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`
`make && ./demo`
+14 -79
View File
@@ -4,91 +4,26 @@
#include <string.h>
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;
}
+167 -167
View File
@@ -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);
}
}