← index
Remember.Words/source/remember.c
Source: Remember.Words/source/remember.c
/*
 
 Remember Words, memory game
 
 I used to play this game with my speech therapist after being in a coma
 and having to learn how to speak again. Helps with memory recall
 so I decided to code it into a computer program.
 
 Hope this can help anyone
 
 - Jared
 
*/
#include "remember.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdarg.h>


void safe_append(char *dest, const char *src, size_t dest_size) {
    char temp[dest_size];
    if (strlen(dest) + strlen(src) + 1 > dest_size) {
        fprintf(stderr, "Error: buffer overflow prevented\n");
        return;
    }
    snprintf(temp, sizeof(temp), "%s%s", dest, src);
    snprintf(dest, dest_size, "%s", temp);
}


/* initalize Rmember structure */
void rem_init(struct Remember *rem) {
    rem->pos = 0;
    rem->buffer[0] = 0;
    rem->match_buffer[0] = 0;
    rem->list.next = NULL;
    rem->list.buffer = NULL;
    rem->count = 1;
    rem->word_count = 0;
}

/* free linked list node */
void ListNode_free(struct ListNode *node) {
    if(node->buffer != NULL) {
        free(node->buffer);
    }
    if(node->next != NULL)
        ListNode_free(node->next);
    
    free(node);
}

/* free Remember structure */
void rem_free(struct Remember *rem) {
    if(rem->list.buffer != NULL)
        free(rem->list.buffer); 
    if(rem->list.next != NULL)
        ListNode_free(rem->list.next);
}

/* add cahracter to buffer */
void rem_addchar(struct Remember *rem, int code) {
    rem->buffer[rem->pos++] = code;
    rem->buffer[rem->pos] = 0;
}

/* delete a character from the buffer */
void rem_delchar(struct Remember *rem) {
    if(rem->pos > 0) {
        rem->buffer[--rem->pos] = 0;
    }
}

/* print the list to stdout */
void rem_printlist(struct Remember *rem) {
    struct ListNode *node = &rem->list;
    while(node != NULL) {
        if(node->buffer != 0)
            printf("%s\n", node->buffer);
        node = node->next;
    }
}
/* build the list from a text file one word per line */
void rem_buildlist(struct Remember *rem, const char *list_file) {
    FILE *fptr = fopen(list_file, "r");
    if(!fptr) {
        fprintf(stderr, "Error opening file: %s\n", list_file);
        exit(EXIT_FAILURE);
    }
    struct ListNode *node = &rem->list;
    while(!feof(fptr)) {
        char buffer[1024];
        if(fgets(buffer, 1024, fptr) != NULL) {
            buffer[strlen(buffer)-1] = 0;
            node->buffer = (char*)malloc(sizeof(char)*strlen(buffer)+1);
            strncpy(node->buffer, buffer, strlen(buffer));
            node->buffer[strlen(buffer)] = 0;
            node->next = (struct ListNode*) calloc(1, sizeof(struct ListNode));
            node->next->next = 0;
            node = node->next;
            rem->word_count++;
        }
    }
    fclose(fptr);
}

/* gen a word from the linked list */
char *gen_word(struct Remember *rem, int index) {
    struct ListNode *node = &rem->list;
    int i = 0;
    while(node != 0 && i < index) {
        node = node->next;
        ++i;
    }
    return node->buffer;
}
/* gen words for comparaision */
void rem_genwords(struct Remember *rem) {
    for(int i = 0; i < rem->count; ++i) {
        int random = rand()%(rem->word_count-1);
        if(i > 0) {
            strncat(rem->match_buffer, " ", BUFFER_MAX-1);
            strncat(rem->match_buffer, gen_word(rem, random), BUFFER_MAX-1);
        }
        else
            snprintf(rem->match_buffer, BUFFER_MAX-1, "%s",gen_word(rem, random));
    }
    rem->count++;
}
/* compare words */
int rem_compare(struct Remember *rem) {
    if(strcmp(rem->buffer, rem->match_buffer) == 0) {
        return 1;
    }
    return 0;
}
/* restart */
void rem_restart(struct Remember *rem) {
    rem->pos = 0;
    rem->buffer[0] = 0;
    rem->match_buffer[0] = 0;
}
/* varaiable argument printf to on screen buffer */
void rem_printf(struct Remember *rem, const char *format, ...) {
    char buffer[BUFFER_MAX];
    va_list args;
    va_start(args, format);
    vsprintf(buffer,format, args);
    perror(buffer);
    va_end(args);
    safe_append(rem->buffer, buffer, BUFFER_MAX);
}