'Organise multiple fixed-length-string dictionaries for "sparse" string-lengths

I need to load some fixed-length-string dictionaries from disk: count of word-lengths ( 1 .. 18 ), word-lengths ( 3 .. 20 ), word-counts ( 1 .. N ) for each word-length ( N < 50,000 ) are all unknown until run-time.

I'm new to C and just about coping with array-of-string:

char (*words5)[6]; // my word-lengths don't count \0 ...to preserve sanity
words5 = calloc(wordcnt * sizeof *words5);

That's fine for one dictionary, but I will have 1 .. 18 different dictionaries. It seems "untidy" to have:

char (*words3)[4];
char (*words4)[5];
...
char (*words20)[21];

when most will be unused for most runs of the programme.

What is a better way of "organising" these dictionaries?

Chris

c


Solution 1:[1]

I finally got it going!

edit: OH NO I DIDN'T! -- this seems to do ONE wordlen and segfaults when I do more stuff that generates (e.g.): thislen = 7; int thiscnt = 10;

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

#define MAX_WORDLEN 10 // maximum word-length for test ( sans \0 )

// bounds: index is word-length ( sans \0 ), int is word-count
int wordcnts[MAX_WORDLEN + 1] = {0}; // +1 to get index = MAX_WORDLEN

// dictionaries
char *dicts[MAX_WORDLEN + 1];   // +1 to get an index = MAX_WORDLEN
    
int main(void) {
    
    // do stuff that generates:
    int thislen = 4; // word-length of interest ( sans \0 )
    int thiscnt = 9; // count of thislen words surviving the filters
    

    char (*dicts[thislen])[thislen + 1]; // +1 for \0
    dicts[thislen] = malloc(thiscnt * sizeof(*dicts[thislen]));
    if ( dicts[thislen] == NULL ) {
        printf("malloc fail! len %d, cnt %d\n", thislen, thiscnt);
        exit(EXIT_FAILURE); 
    }
    wordcnts[thislen] = thiscnt;                                            
    

    // copy some dummy strings into dicts[thislen]
    strncpy(dicts[thislen][0], "ABLE", thislen + 1);
    strncpy(dicts[thislen][1], "BODY", thislen + 1);
    strncpy(dicts[thislen][2], "COPE", thislen + 1);
    strncpy(dicts[thislen][3], "DEER", thislen + 1);
    strncpy(dicts[thislen][4], "MANY", thislen + 1);
    strncpy(dicts[thislen][5], "MORE", thislen + 1);
    strncpy(dicts[thislen][6], "XIPE", thislen + 1);
    strncpy(dicts[thislen][7], "YELL", thislen + 1);
    strncpy(dicts[thislen][8], "ZOOS", thislen + 1);
    
    for (int i = 0; i < wordcnts[thislen]; ++i) {
        printf("[%d]: %s\n", i, dicts[thislen][i]);
    }

    // free when done
    for (int i = 0; i <= MAX_WORDLEN; ++i) {
        if (wordcnts[i] > 0) {
            free(dicts[i]);
        }
    }
    return 0;
}

/* OUTPUT
me@testbox Tests % ./malloc_strings1   
[0]: ABLE
[1]: BODY
[2]: COPE
[3]: DEER
[4]: MANY
[5]: MORE
[6]: XIPE
[7]: YELL
[8]: ZOOS
me@testbox Tests %
*/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1