changed structure
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
een programma dat newlines leest en ze dan weer print
|
||||
|
||||
we gaan een scanf moeten maken die newlines leest en dan malloced voor elke
|
||||
string
|
||||
|
||||
scanf lijkt automatisch te stoppen op newlines, maar gaat wel onmiddelijk door totdat alle scanf's satisfied zijn
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WORDCOUNT 5
|
||||
|
||||
void storeinput(char input[], int index, char **strarr) {
|
||||
char *myword = malloc(strlen(input) +1);
|
||||
//*myword = *input; //blijkbaar hier strcpy voor nodig, want anders overwrite
|
||||
//ik hier alleen maar de value van de pointer zelf
|
||||
strcpy(myword, input); //myword is a pointer to allocated memory, but it's empty unless strcopy
|
||||
printf("myword:%s\n", myword);
|
||||
strarr[index] = myword;
|
||||
printf("strarr:%s\n", strarr[index]);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// laten we eerst een array van pointers naar strings maken
|
||||
char **strarr = malloc(sizeof(char *) * 10);
|
||||
|
||||
// moeten nu een functie maken die individuele strings malloced?
|
||||
|
||||
for (int i = 0; i < WORDCOUNT; i++) {
|
||||
char temp[50];
|
||||
scanf("%s", temp);
|
||||
storeinput(temp, i, strarr);
|
||||
printf("wordin:%d %s\n", i, temp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < WORDCOUNT; i++) {
|
||||
printf("word:%d, %s\n", i, strarr[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
take input
|
||||
decide if hex or binary
|
||||
then convert
|
||||
then print
|
||||
|
||||
let's convert binary to hex first
|
||||
for each byte, split into nibble,
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//might have to add some padding, but basic works
|
||||
void bintohex(char* string_in){
|
||||
const char hexmap[] = "0123456789ABCDEF";
|
||||
char hexnum[4] = {};
|
||||
int stringl = strnlen(string_in, 10)-1;
|
||||
//aantal nibbles
|
||||
int loopamount = stringl/4;
|
||||
printf("totalstringlength=%d\n", stringl);
|
||||
for (int loopcount = 0; loopcount < loopamount; loopcount++) {
|
||||
int bin2dec = 0;
|
||||
//rechts naar links in nibble
|
||||
for (int nibbledigit = 0 ; nibbledigit <4 ; nibbledigit++) {
|
||||
//nibblecount + current
|
||||
int targetdigit = loopcount*4+(4-1-nibbledigit);
|
||||
//check if j+i = 1
|
||||
//printf("nibbledigit:%d=%c=%i\n", j, string_in[targetdigit],1<<j);
|
||||
bin2dec += 1 * (string_in[targetdigit]-'0')*1<<(nibbledigit);
|
||||
}
|
||||
hexnum[loopcount]=hexmap[bin2dec];
|
||||
printf("nibble:%i=%d\n",loopcount,bin2dec);
|
||||
}
|
||||
printf("hex=%s", hexnum);
|
||||
}
|
||||
|
||||
int main(){
|
||||
printf("input either binary or hexadecimal\n");
|
||||
char buff[32+2]; //4bytes+\n+null
|
||||
fgets(buff, sizeof(buff), stdin);
|
||||
bintohex(buff);
|
||||
}
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
#ifndef HASH_FNV_H
|
||||
#define HASH_FNV_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t hasher(void *data, size_t len);
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "stringchicken.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char myString[100];
|
||||
char ch;
|
||||
FILE *fptr = fopen(argv[1], "r");
|
||||
|
||||
if (fptr == NULL) {
|
||||
printf("file doesn't exist");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct stringchicken *mystringarray = create_string_chicken();
|
||||
|
||||
while (fgets(myString, 100, fptr)) {
|
||||
push_SC(myString, mystringarray);
|
||||
}
|
||||
|
||||
print_SC(mystringarray);
|
||||
int mylength = strnlen(myString, 100);
|
||||
|
||||
fclose(fptr);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
dit is een test
|
||||
test2
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "stringchicken.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
parser that can read K=V, maybe also K:V? although would just be configurable seperator
|
||||
I know python uses dictionary which uses a hash table so key -> hash -> value table
|
||||
for this assignment, I could use 2 arrays? though that's... a bit dangerous? or at least tricky, in terms of reassignments.
|
||||
let's just go with a struct with 2 dynamic arrays where the indices are aligned
|
||||
|
||||
ik neem dus eerst 1 die het omzet naar een struct van strings, dan een struct van de KV values.
|
||||
*/
|
||||
|
||||
struct stringchicken *create_string_chicken(){
|
||||
struct stringchicken *mystruct = malloc(sizeof(struct stringchicken));
|
||||
mystruct->length = 0;
|
||||
mystruct->capacity = 2;
|
||||
|
||||
mystruct->data = malloc(sizeof(char*) * mystruct->capacity);
|
||||
|
||||
return mystruct;
|
||||
}
|
||||
|
||||
void push_SC(char *string_input, struct stringchicken *struct_input){
|
||||
if (struct_input->length == struct_input->capacity) {
|
||||
struct_input->capacity*=2;
|
||||
char **tempptr = realloc(struct_input->data, sizeof(char*) * struct_input->capacity);
|
||||
|
||||
if (tempptr == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct_input->data = tempptr;
|
||||
}
|
||||
|
||||
char *newstring = malloc(strnlen(string_input, 101)+1);
|
||||
strcpy(newstring,string_input);
|
||||
struct_input->data[struct_input->length] = newstring;
|
||||
|
||||
struct_input->length++;
|
||||
}
|
||||
|
||||
void free_SC(struct stringchicken *struct_input){
|
||||
for (int i = 0; i < struct_input->length; i++) {
|
||||
free(struct_input->data[i]);
|
||||
}
|
||||
free(struct_input->data);
|
||||
free(struct_input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void print_SC(struct stringchicken *input_struct){
|
||||
for (size_t i = 0; i < input_struct->length; i++) {
|
||||
printf("line:%zu equals %s", i, input_struct->data[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef STRINGCHICKEN_H
|
||||
#define STRINGCHICKEN_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct stringchicken{
|
||||
char **data;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
struct stringchicken *create_string_chicken(void);
|
||||
void push_SC(char *string_input, struct stringchicken *struct_input);
|
||||
void print_SC(struct stringchicken *input_struct);
|
||||
|
||||
#endif // STRINGCHICKEN_H
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
todo
|
||||
change intarray into str array
|
||||
make push array malloc for new str
|
||||
make input strings instead of int (should use fgets?)
|
||||
*/
|
||||
|
||||
struct StringArray{
|
||||
char **data;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
void print_SA(struct StringArray *in_str) {
|
||||
for (size_t i = 0; i < in_str->length; i++) {
|
||||
printf("word:%zu = %s\n", i, in_str->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
struct StringArray *SA_create(size_t in_capacity) {
|
||||
struct StringArray *mystr = malloc(sizeof(struct StringArray)); //allocate memory for struct
|
||||
|
||||
mystr->data = malloc(sizeof(char*) * in_capacity); //make sure the pointer in the struct points to the array
|
||||
mystr->length = 0; //forgot to actually assign a value to the struct
|
||||
mystr->capacity = in_capacity;
|
||||
|
||||
if (mystr->data == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return mystr;
|
||||
}
|
||||
|
||||
int get_string_len(char *in_string){
|
||||
int length = 0;
|
||||
char currchar;
|
||||
do {
|
||||
currchar = in_string[length];
|
||||
length++;
|
||||
}
|
||||
while (currchar != '\0');
|
||||
|
||||
printf("length of word: %d\n", length); //for some reason length is always 2 more than expected, so 1 more than necessary? apparently because of \n, not sure how to filter that.
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/* push value to struct, also handle realloc */
|
||||
void SA_push(char *in_string, struct StringArray *in_str){
|
||||
if (in_str->length == in_str->capacity) { //check if already full
|
||||
in_str->capacity*=2; //if so we should double
|
||||
printf("array capacity is now:%zu\n", in_str->capacity);
|
||||
char **temp; //create a temporary pointer
|
||||
temp = realloc(in_str->data, sizeof(char*)*in_str->capacity); //realloc the data into a new bucket
|
||||
if(temp == NULL){exit(0);}; //check if actually valid
|
||||
in_str->data = temp; //if valid, make sure the pointer in the struct points to the realloced block
|
||||
}
|
||||
|
||||
char *newword = malloc(sizeof(char) * get_string_len(in_string)); //allocate memory for new string, apparantly my function already includes the length of null term
|
||||
strcpy(newword, in_string); //copy word into memory
|
||||
in_str->data[in_str->length] = newword;
|
||||
printf("word:%zu = %s\n", in_str->length, in_str->data[in_str->length]);
|
||||
in_str->length++; //didn't read the flow when transferring and accidentally put this in the if block
|
||||
printf("array length is now:%zu\n", in_str->length);
|
||||
//also had an off-by-one error because I increased length before doing anything
|
||||
}
|
||||
|
||||
|
||||
void SA_free(struct StringArray *inp_str) {
|
||||
for (size_t i = 0; i < inp_str->length; i++) { //for each pointer in array
|
||||
free(inp_str->data[i]); //free at pointer
|
||||
}
|
||||
free(inp_str->data); //free pointer to pointers
|
||||
free(inp_str); //free the struct
|
||||
}
|
||||
|
||||
int main() {
|
||||
srand(time(NULL));
|
||||
printf("input words:\n");
|
||||
|
||||
struct StringArray *mystringarraystr = SA_create(2);
|
||||
|
||||
char input[50];
|
||||
do{
|
||||
fgets(input, sizeof(input), stdin); //get input from stdin of size input[] and put it in input
|
||||
SA_push(input, mystringarraystr); //push the value of input into mystr
|
||||
} while (*input != '-');
|
||||
|
||||
print_SA(mystringarraystr);
|
||||
|
||||
SA_free(mystringarraystr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
Since you are currently navigating the transition from "fixed-size" allocation (calculating everything upfront) to "dynamic" allocation (growing as you go), the best way to learn is to build in stages.
|
||||
|
||||
The reason you didn't need a `count` or `capacity` in your `Darray` is that you did **Pre-Calculation**: you figured out exactly how many digits were in the number before you called `malloc`.
|
||||
|
||||
But for user input, you can't pre-calculate. You need **Dynamic Growth**.
|
||||
|
||||
Here is a learning path split into 4 sub-assignments.
|
||||
|
||||
---
|
||||
|
||||
### Assignment 1: The "Fixed" Dynamic Array
|
||||
**Goal:** Master the basic Struct $\rightarrow$ Pointer relationship.
|
||||
**Task:** Create a program that asks the user "How many numbers do you want to enter?".
|
||||
1. Create a struct `IntArray` with `int *data` and `size_t length`.
|
||||
2. `malloc` the struct.
|
||||
3. `malloc` the `data` array based on the user's number.
|
||||
4. Fill it, print it, and free it.
|
||||
**Key Lesson:** Understanding that the struct is the "handle" and the pointer is the "payload."
|
||||
|
||||
---
|
||||
|
||||
### Assignment 2: The "Growing" Dynamic Array
|
||||
**Goal:** Understand `capacity` vs `length` and `realloc`.
|
||||
**Task:** Modify Assignment 1, but **don't** ask the user for the size upfront.
|
||||
1. Add `size_t capacity` to your struct.
|
||||
2. Start `capacity` at 2.
|
||||
3. Use a `while` loop to take input until the user types `-1`.
|
||||
4. Inside the loop: If `length == capacity`, use `realloc` to double the `capacity`.
|
||||
**Key Lesson:** `length` is how many items are *actually there*; `capacity` is how many items *can fit* before you need more memory.
|
||||
|
||||
---
|
||||
|
||||
### Assignment 3: The "Pointer to Pointers" (The String Array)
|
||||
**Goal:** Understand "Deep Allocation" (Double Indirection).
|
||||
**Task:** Change your `IntArray` to a `StringArray`.
|
||||
1. Your struct now has `char **words`.
|
||||
2. When you `realloc` the `words` array, you are only making room for more **addresses** (pointers).
|
||||
3. For every string the user enters, you must `malloc` a **new** piece of memory for that specific string and `strcpy` the input into it.
|
||||
**Key Lesson:** A `char**` is just an array of pointers. The array itself is one allocation, but every string it points to is a *separate* allocation.
|
||||
|
||||
---
|
||||
|
||||
### Assignment 4: The "Deep Free"
|
||||
**Goal:** Prevent memory leaks in complex structures.
|
||||
**Task:** Write a dedicated `free_string_array(StringArray *sa)` function.
|
||||
1. It must loop through the array and `free()` every individual string first.
|
||||
2. Then it must `free()` the `words` pointer array.
|
||||
3. Finally, it must `free()` the struct itself.
|
||||
**Key Lesson:** You must free memory in the exact reverse order that you allocated it.
|
||||
|
||||
---
|
||||
|
||||
### The "Scaffold" (Start here for Assignment 3/4)
|
||||
|
||||
If you want to jump straight to the strings, here is a clean scaffold. I have left "TODOs" where the logic should go.
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
char **words;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
} StringArray;
|
||||
|
||||
// Initialize the "Manager" struct
|
||||
StringArray* create_sa() {
|
||||
StringArray *sa = malloc(sizeof(StringArray));
|
||||
sa->length = 0;
|
||||
sa->capacity = 4; // Start small to force realloc to happen
|
||||
sa->words = malloc(sizeof(char*) * sa->capacity);
|
||||
return sa;
|
||||
}
|
||||
|
||||
void add_word(StringArray *sa, const char *input) {
|
||||
// TODO 1: Check if length == capacity.
|
||||
// If so, use realloc to double the capacity of sa->words.
|
||||
|
||||
// TODO 2: Allocate memory for the new string.
|
||||
// Hint: strlen(input) + 1
|
||||
|
||||
// TODO 3: Copy the input into the newly allocated memory.
|
||||
|
||||
// TODO 4: Store that pointer in sa->words[sa->length] and increment length.
|
||||
}
|
||||
|
||||
void free_sa(StringArray *sa) {
|
||||
// TODO 5: Loop through sa->words and free each individual string.
|
||||
|
||||
// TODO 6: Free the sa->words array itself.
|
||||
|
||||
// TODO 7: Free the sa struct.
|
||||
}
|
||||
|
||||
int main() {
|
||||
StringArray *myList = create_sa();
|
||||
char temp[100];
|
||||
|
||||
printf("Enter words (type 'exit' to stop):\n");
|
||||
while (scanf("%99s", temp) == 1 && strcmp(temp, "exit") != 0) {
|
||||
add_word(myList, temp);
|
||||
}
|
||||
|
||||
printf("\nStored words:\n");
|
||||
for (size_t i = 0; i < myList->length; i++) {
|
||||
printf("%zu: %s\n", i, myList->words[i]);
|
||||
}
|
||||
|
||||
free_sa(myList);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Final tip on your `Darray` logic:
|
||||
In your `Darray` code, you did:
|
||||
`DigDarr->digits = (int *)(DigDarr + 1);`
|
||||
|
||||
This is very "clever" code, but in professional C, it is often avoided unless you are writing a high-performance kernel or library. It makes the code harder to read and makes `realloc` almost impossible (because the data is physically glued to the struct).
|
||||
|
||||
**The standard way** is to have the struct hold a pointer to a separate block of memory. It's slightly slower (one extra pointer jump), but it's much safer and more flexible.
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
idee, een programma dat een lijst van strings krijgt, en ze dan sorteert op
|
||||
alphabetische volgorde, idealiter ook met hele nummbers if relevant (dus niet
|
||||
alleen individuele digits)
|
||||
|
||||
split into strings and numbers
|
||||
|
||||
okay dit werkt nu omzetten naar strings
|
||||
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define WORDS 16
|
||||
#define WORDLENGTH 64
|
||||
|
||||
/* return 1 if word1 < word 2*/
|
||||
int compareword(char word1[], char word2[]) {
|
||||
for (int i = 0; i < WORDLENGTH; i++) {
|
||||
if (word1[i] == word2[i]) {
|
||||
//it should continue
|
||||
}
|
||||
else if (word1[i] < word2[i]) {
|
||||
printf("%s is larger than %s\n", word1, word2);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* eerst gewone bubblesort weer doen */
|
||||
int mybubblesort(char inputarr[WORDS][WORDLENGTH]) {
|
||||
for (int i = 0; i < WORDS - 1; i++) { // voor elk woord
|
||||
for (int j = 0; j < WORDS - 1; j++) { // ga langs elk woord
|
||||
if (compareword(inputarr[j], inputarr[j + 1])) { // als huidig nummer groter is
|
||||
// swap hem dan
|
||||
char temp[64];
|
||||
strcpy(temp, inputarr[j+1]);
|
||||
strcpy(inputarr[j+1], inputarr[j]);
|
||||
strcpy(inputarr[j], temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < WORDS - 1; i++) {
|
||||
if (inputarr[i][0] > 0) {
|
||||
printf("num:%i, %s\n", i, inputarr[i]);
|
||||
}
|
||||
//puts(inputarr[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
char mytest[16][64] = {"pear", "watermelon", "aap", "apple", "banana", "cantaloupe", "Elephant", "Zebra"};
|
||||
|
||||
srand(time(NULL));
|
||||
mybubblesort(mytest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
#include <ncurses.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
int main(){
|
||||
initscr();
|
||||
noecho();
|
||||
cbreak();
|
||||
keypad(stdscr, TRUE);
|
||||
curs_set(1);
|
||||
|
||||
if(has_colors() == FALSE ) {
|
||||
endwin();
|
||||
puts("no colors");
|
||||
return 1;
|
||||
}
|
||||
|
||||
start_color();
|
||||
init_pair(1, COLOR_WHITE, COLOR_BLUE);
|
||||
attron(COLOR_PAIR(1));
|
||||
|
||||
int y,x;
|
||||
getmaxyx(stdscr, y,x);
|
||||
y=y*0.5;
|
||||
x=(x*0.5) -6;
|
||||
mvwprintw(stdscr, y, x, "Hello World");
|
||||
mvwprintw(stdscr, 2, 2, "Hellow World1");
|
||||
refresh();
|
||||
|
||||
attroff(COLOR_PAIR(1));
|
||||
|
||||
getch();
|
||||
|
||||
endwin();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user