如何在不创建变量的情况下将项添加到结构中

时间:2016-11-10 08:57:57

标签: c struct

我使用struct来存储字符串和整数,如下所示:

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

我可以通过执行此操作将项添加到结构中

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

我想要实现的最终结果是收集用户输入(例如"右20"),并将其存储在结构中。如何在不使用变量(m1,m2等)的情况下将未知数量的用户输入存储到结构中,因为我不知道最后会有多少项。

3 个答案:

答案 0 :(得分:4)

听起来好像你真的想要将值存储到结构中,而不是想要存储一系列独立的结构实例;每个用户输入一个。

这样做的三个最基本的方法是:

  • 一个数组,其大小在编译时选择。它不应该太难以使它足够大"为了合理的输入
  • 您在运行时设置(然后成长)的大小的数组
  • 结构实例的链接列表

更喜欢哪一个取决于您认为哪个最简单。如果可能的话,静态附加内容总是最简单的。您可以轻松拥有类似

的内容
struct movement movements[10000];

在全球范围内,这在64位系统上的成本可能只有120 KB。请注意,这并不包含direction字符串的内存;如果那些总是从"右边"和"左" (也许" up" /" down"你也可以将它表示为枚举:

enum direction { DIRECTION_LEFT = 0, DIRECTION_RIGHT, DIRECTION_UP, DIRECTION_DOWN };

这将使结构"自包含"和(在64位系统上)较小,因为枚举将小于指针。

使用realloc()动态增长数组并不太难,你可以像往常一样轻松地查看它。

答案 1 :(得分:2)

使用链接列表。它是一个递归的数据结构,可以满足您的需求。

以前是我刚才写的一些示例代码可能会有所帮助:

#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);
    }
}

答案 2 :(得分:-1)

使用LinkedList存储无限数量的移动。 对于每个移动,在链接列表中创建一个节点并更新下一个指针。

struct node {
  struct movement m;
  node* next;
}