To expand on my comment, the X macro technique can be used for this. See here, for example
The idea is that we define the list once, for example
#define STRINGLIST \
X( "alice") \
X( "bob") \
X( "cat")
When we want to use this list, we invoke the above macro, having defined the macro X:
static const char *const DStr[] = {
#define X(S) S,
STRINGLIST
#undef X
};
static const unsigned short DLen[] = {
#define X(S) sizeof( S)-1,
STRINGLIST
#undef X
};
This way we only have to define the strings once, and guarantee that the arrays DStr and DLen are in the same order. The disadvantage is that it looks pretty bizarre first time you see it, and others maintaining your code might be boggled.