Ryan Chia Ryan Chia - 29 days ago 5
C Question

How can I add items into a struct without creating variables

I am using a struct to store a string and an integer like so:

struct movement {
char *direction;
int steps;
};


I can add items into the struct by doing this

struct movement m1= { "right",20 };
struct movement m2= { "left" ,10 };


The end result I am trying to achieve is to collect user inputs (e.g. "right 20"), and store it in the struct. How can I store an unknown number of user inputs into the struct without the use of variables (m1, m2 etc) since I will not know how many items there will be at the end.

Answer

Use a linked list. It is a recursive data structure which would be great for what you want.

Here is some example code I wrote a while ago that might help:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* basic linked list structure */
typedef struct node node_t;

struct node {
    char *direction;
    int steps;
    node_t *next;
};

/* pointers to the head and tail of the list */
typedef struct {
    node_t *head;
    node_t *foot;
} list_t;

list_t *initialize_list(void);
list_t *insert_nodes(list_t *list, char *direction, int steps);
void free_list(list_t *list);
node_t *generate_node(void);
void print_list(list_t *list);
void exit_if_null(void *ptr, const char *msg);

int
main(int argc, char const *argv[]) {
    list_t *list;

    /* empty list created */
    list = initialize_list();

    /* inserting information one a time */
    list = insert_nodes(list, "right", 20);
    list = insert_nodes(list, "left", 10);

    print_list(list);

    /* freeing list at the end */
    free_list(list);
    list = NULL;

    return 0;
}

/* function to insert information into a node */
list_t
*insert_nodes(list_t *list, char *direction, int steps) {

    /* called generate_node() to create a new node */
    node_t *new;
    new = generate_node();

    /* puts steps information into node */
    new->steps = steps;

    /* allocates space for direction string */
    /* this is needed because *direction is a pointer */
    new->direction = malloc(strlen(direction)+1);

    /* copies direction info into node */
    strcpy(new->direction, direction);

    /* inserting information at the tail of the list */
    new->next = NULL;

    if (list->foot == NULL) {
        /* first insertion into list */
        list->head = list->foot = new;
    } else {
        list->foot->next = new;
        list->foot = new;
    }

    /* returns modified list */
    return list;
}

.* function which generates new nodes */
node_t
*generate_node(void) {
    node_t *newnode;

    /* create space for new node */
    newnode = malloc(sizeof(*newnode));
    exit_if_null(newnode, "Allocation");

    /* initialize node info to nothing */
    newnode->direction = NULL;
    newnode->steps = 0;

    return newnode;
}

/* creates the empty linked list */
list_t 
*initialize_list(void) {
    list_t *list;

    create space for list */
    list = malloc(sizeof(*list));
    exit_if_null(list, "Allocation");

    /* set pointers to NULL */
    /* We don't want them pointing at anything yet */
    list->head = list->foot = NULL;

    return list;
}

/* function which prints entire list */
void
print_list(list_t *list) {

    /* start at the head of the list */
    node_t *curr = list->head;

    while (curr) {
        printf("%s %d\n", curr->direction, curr->steps);

        /* steps through the list */
        curr = curr->next;
    }
}

/* function which frees nodes */
void
free_list(list_t *list) {
    node_t *curr, *prev;

    /* start at beginning of list */
    curr = list->head;

    /* frees nodes one at a time */
    while(curr) {
        prev = curr;
        curr = curr->next;
        free(prev);
    }

    /* frees entire list */
    free(list);
}

/* function which checks malloc(), and whether enough space was allocated */
void
exit_if_null(void *ptr, const char *msg) {
    if (!ptr) {
        printf("Unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}