I know this answer will be a little bit over the top, but here is what I would do....
It's half way to an in-memory database 
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N_FIELDS 5
struct Record {
char *field[N_FIELDS];
};
struct Table {
struct Record *records;
int records_used;
int records_allocated;
int grow_by;
};
static struct Table *table_new(int grow_by) {
if(grow_by < 0) return NULL;
struct Table *table = malloc(sizeof(struct Table));
if(table == NULL) return NULL;
table->grow_by = grow_by;
table->records = NULL;
table->records_allocated = 0;
table->records_used = 0;
return table;
}
static int table_add_record(struct Table *table) {
// Grow the table of if needed
if(table->records_used == table->records_allocated) {
printf("Adding %d more records\n", table->grow_by);
struct Record *new_records = realloc(table->records,sizeof(struct Record)*(table->records_allocated+table->grow_by));
if(new_records == NULL)
return -1; // Failed
table->records = new_records;
table->records_allocated += table->grow_by;
}
// Add the new record to the end (should really check for errors...)
int this_record = table->records_used;
for(int i = 0; i < N_FIELDS; i++)
table->records[this_record].field[i] = NULL;
table->records_used++;
return this_record;
}
static void table_set_field(struct Table *table, int rec_no, int field_no, char *value) {
if(field_no >= N_FIELDS) return;
if(table->records[rec_no].field[field_no] != NULL)
free(table->records[rec_no].field[field_no]);
if(value != NULL)
table->records[rec_no].field[field_no] = strdup(value);
else
table->records[rec_no].field[field_no] = NULL;
}
static void table_print(struct Table *table) {
printf("%d out of %d records used\n",table->records_used, table->records_allocated);
for(int i = 0; i < table->records_used; i++) {
printf("%3d:",i);
printf(", %s",table->records[i].field[0]);
for(int j = 1; j < N_FIELDS; j++) {
printf(", %s",table->records[i].field[j]);
}
printf("\n");
}
}
static void table_free(struct Table *table) {
for(int i = 0; i < table->records_used; i++) {
for(int j = 0; j < N_FIELDS; j++) {
free(table->records[i].field[j]);
}
}
free(table->records);
free(table);
}
//===========================================================================
int main(int argc, char *argv[]) {
struct Table *t = table_new(5);
// As a test, add 30 records
for(int i = 0; i < 28; i++ ) {
int rec_no = table_add_record(t);
table_set_field(t, rec_no, 0, "a");
table_set_field(t, rec_no, 1, "b");
table_set_field(t, rec_no, 2, "dog");
table_set_field(t, rec_no, 3, "cat");
table_set_field(t, rec_no, 4, "mouse");
}
table_print(t);
table_free(t);
return 0;
}