made examples/demos for vectors && files && lists | also fixed a bug with the vector and list size and popping, explained in the adjacent comment

This commit is contained in:
Odweta
2023-12-22 19:04:08 +01:00
parent 2f1c78ce52
commit b9c93116bc
9 changed files with 146 additions and 75 deletions
+17 -4
View File
@@ -2,6 +2,12 @@
I got bored with having to use complicated checking and stuff when working with files and arrays in C, so I implemented a new `file_t` struct which can load the contents of a file into a dynamically allocated array (yes, there is an implementation of those here as well... (`vector_t` struct)). The struct also stores the number of lines the file has.
Also, I managed to come up with an implementation of a Python-like list (a vector of vectors of any type interpreted as just one vector). Quite handy, I'd say. The `list_t` struct is what you want to use when working with lists.
The difference between a `vector_t` and a `list_t` is that a vector can only be of one type, whereas a list can have values of any type inside it (in this context, any means types defined in this library and default types in C).
Examples of this work of art are in the `/examples/` directory of this repo.
## Files
#### What works so far:
@@ -13,6 +19,12 @@ I got bored with having to use complicated checking and stuff when working with
1. File writing logic
2. File appending logic
3. Copy a file to another file
4. Move a file to another file
5. Rename a file
6. Delete a file
7. Empty a file
8. Add line numbers at the beggining of each line in a file
+ You tell me
@@ -31,6 +43,7 @@ I got bored with having to use complicated checking and stuff when working with
#### TODO:
1. Removing an element at a given index
2. Vectors of lists
+ You tell me
@@ -47,10 +60,10 @@ I got bored with having to use complicated checking and stuff when working with
#### TODO:
+ Inserting at a given index
+ Verify multi-dimensional lists working
+ Get/set at a given index
+ Remove at a given index
1. Inserting at a given index
2. Verify multi-dimensional lists working - lists of lists
3. Get/set at a given index
4. Remove at a given index
## Installation
+13 -33
View File
@@ -1,41 +1,21 @@
#include <odweta/list.h>
#include <odweta/vector.h>
#include <stdio.h>
int main(int argc, char **argv) {
list_t *l = listInit();
int main() {
printf("creating a vector using 'vectorInit(<type>)' (returns a vector_t*)\npossible type are: INT, FLOAT, CHAR, VECTOR (LIST in the future)\n");
vector_t* v = vectorInit(INT);
vector_t *to_be_pushed_vec = vectorInit(INT);
vectorPush(to_be_pushed_vec, &(int){1620});
listPush(l, VECTOR, (vector_t *)to_be_pushed_vec);
listPush(l, FLOAT, &(float){3.14});
listPush(l, CHAR, &(char){'x'});
listPush(l, INT, &(int){123});
printf("pushing an integer value into the vector\nnote the kind of unusual way of passing the number argument: if you want to pass an expression (e.g. the value '1' or '4*4'), something not stored in a variable, you follow this syntax - &(type){value} (e.g. &(int){1 + 1})\n->'vectorPush(vector_t*, &(int){123})'\n");
vectorPush(v, &(int){123});
vectorPrint(v);
listPrint(l);
printf("popping the last value of the vector; in this case, it is an integer, so you type: 'int poppedValue = *((int *)vectorPop(vector_t*))'\n");
int poppedValue = *((int *)vectorPop(v));
printf("popped: %d\n", poppedValue);
vectorPrint(v);
printf("popping for the 1st time\n");
int popped = *((int *)listPop(l));
printf("if you are finished working with the vector BEFORE the immediate end of the program, run 'vectorCleanup(vector_t*)', otherwise it is not strictly necessary\n");
vectorCleanup(v);
printf("popped: %d\n", popped);
listPrint(l);
printf("popping for the 2nd time\n");
char cpopped = *((char *)listPop(l));
printf("popped: '%c'\n", cpopped);
listPrint(l);
printf("popping for the 3rd time\n");
float fpopped = *((float *)listPop(l));
printf("popped: %f\n", fpopped);
listPrint(l);
listCleanup(l);
return 0;
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
#include <odweta/file.h>
#include <stdio.h>
int main() {
printf("creating a file using 'fileInit(<filename>)' (returns a file_t*)\n");
file_t* f = fileInit("test.txt");
printf("printing the file contents\n\n");
filePrint(f);
printf("\nconvering the file contents into a string (char*)\n");
char* string = fileToString(f);
printf("\"%s\"\n", string);
// TODO -> writing, clearing
printf("if you are finished working with the file BEFORE the immediate end of the program, run 'fileCleanup(file_t*)', otherwise it is not strictly necessary\n");
fileCleanup(f);
return 0;
}
+6
View File
@@ -0,0 +1,6 @@
this !1@#%
is a big
mega such large
test
and
+21
View File
@@ -0,0 +1,21 @@
#include <odweta/list.h>
#include <stdio.h>
int main() {
printf("creating a list using 'listInit()' (returns a list_t*)\n");
list_t* l = listInit();
printf("pushing an integer value into the list\nnote the kind of unusual way of passing the number argument: if you want to pass an expression (e.g. the value '1' or '4*4'), something not stored in a variable, you follow this syntax - &(type){value} (e.g. &(int){1 + 1})\nalso, the type of the variable must be given as the second argument to the function\n->'listPush(list_t*, INT, &(int){123})'\n");
listPush(l, INT, &(int){123});
listPrint(l);
printf("popping the last value of the list; in this case, it is an integer, so you type: 'int poppedValue = *((int *)listPop(list_t*))'\n");
int poppedValue = *((int *)listPop(l));
printf("popped: %d\n", poppedValue);
listPrint(l);
printf("if you are finished working with the list BEFORE the immediate end of the program, run 'listCleanup(list_t*)', otherwise it is not strictly necessary\n");
listCleanup(l);
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
#include <odweta/vector.h>
#include <stdio.h>
int main() {
printf("creating a vector using 'vectorInit(<type>)' (returns a vector_t*)\npossible type are: INT, FLOAT, CHAR, VECTOR (LIST in the future)\n");
vector_t* v = vectorInit(INT);
printf("pushing an integer value into the vector\nnote the kind of unusual way of passing the number argument: if you want to pass an expression (e.g. the value '1' or '4*4'), something not stored in a variable, you follow this syntax - &(type){value} (e.g. &(int){1 + 1})\n->'vectorPush(vector_t*, &(int){123})'\n");
vectorPush(v, &(int){123});
vectorPrint(v);
printf("popping the last value of the vector; in this case, it is an integer, so you type: 'int poppedValue = *((int *)vectorPop(vector_t*))'\n");
int poppedValue = *((int *)vectorPop(v));
printf("popped: %d\n", poppedValue);
vectorPrint(v);
printf("if you are finished working with the vector BEFORE the immediate end of the program, run 'vectorCleanup(vector_t*)', otherwise it is not strictly necessary\n");
vectorCleanup(v);
return 0;
}
+2 -4
View File
@@ -13,15 +13,13 @@ file_t* fileInit(char* path); // initialization function
void fileCleanup(file_t* f); // just to be memory safe...
int fileCountLines(file_t* f); // counts the lines in a file
void filePrint(file_t* f); // prints the file as a string
char* fileToString(file_t* f); // returns a string with the file contents
void fileWriteln(file_t* f, char* line); // appends a given string to the file on a newline
void fileWriteln(file_t* f, char* payload); // appends a given string to the file on a newline
void fileWrite(file_t* f, char* line); // appends a given string to the file (not on a newline!)
void fileWrite(file_t* f, char* payload); // appends a given string to the file (not on a newline!)
void fileClear(file_t* f); // wipes the file contents
+11 -6
View File
@@ -96,12 +96,17 @@ listCleanup(list_t* l) {
void*
listPop(list_t* l) {
vector_t *first_ptr = (vector_t *)vectorPop((vector_t *)l->data);
void *ptr = vectorPop(first_ptr);
l->size -= 1;
if (l->size != 0) {
vector_t *first_ptr = (vector_t *)vectorPop((vector_t *)l->data);
void *ptr = vectorPop(first_ptr);
l->size -= 1;
if (l->size <= l->capacity / 2) l->capacity /= 2;
if (l->capacity == 0) l->capacity = 1;
if (l->size <= l->capacity / 2) l->capacity /= 2;
if (l->capacity == 0) l->capacity = 1;
return ptr;
return ptr;
} else {
// cannot pop when there is no value in the list
return NULL;
}
}
+34 -28
View File
@@ -211,35 +211,41 @@ 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;
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;
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;
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;
if (v->size != 0) {
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;
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;
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;
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;
return vretval;
default:
perror("specify a valid vector type\n");
exit(EXIT_FAILURE);
return vretval;
default:
perror("specify a valid vector type\n");
exit(EXIT_FAILURE);
}
} else {
// cannot pop when there is no value in the vector
return NULL;
}
}