Assign an integer to a single element string array in C

316 views Asked by At

I cannot figure out how to assign an integer value to an array of string in C, assuming this is possible of course! I would like to change some elements from a char ** into different values and then re-assign them to their initial position into the array. Practically, I have two element, "Mon" and "Aug", which I would like to become "01" and "08"... So I tried something but unsuccessfully:

char *time_array[7] = {"45", "55", "11", "Mon", "29", "Aug", "2022"};
uint32_t day2convert = 1;
uint32_t month2convert = 8;
*time_array[3] = &day2convert;    // not even with a cast (char) which gave same results 
*time_array[5] = &month2convert;
for (j = 0; j < 7; ++j) 
printf("after conversion : %s\n", time_array[j]);
/* 

Results for the two elements are different at each main call, as I'm randomly picking values present in different memory allocations (maybe). Es. don, hug; 4on 8ug, ton xug... Moreover i tried also with strcpy function as:

strcpy(time_array[3], &day2convert);   //also with a cast (char)(&day2convert)

but still I retrieve a void string.

So, gently, I'm asking if there could be a way to do what I want in principle, but also asking for some explanations about array of string. Because what I learnt is that a char ** is an array of pointer so it should be right to assign a value to it as *array[ii] = &var (??? in search of confirmation)

2

There are 2 answers

3
Fe2O3 On

You will want to convert each of the 7 day names to a number.

I wrote this "hash function" for quickly getting back 1 to 7 for "Sun" to "Saturday" (it only needs the first two characters of the name, and is case insensitive).

It will return false positives, but allows you to test the string you have against only one possible day name. If the function returns 2, then the string can be checked as a variation of "Tu", "TUE" "Tuesday". You don't have to examine the other six day names as possibilities.

Return of 0 indicates it is not a weekday name.

// Convert a day name (or 3 letter abbrev.) to index (1-7, Sun=1). Beware false positives!
int wkdayOrd( char cp[] ) { return "65013427"[*cp/2 + ~cp[1] & 0x7] & 0x7; }

If you carefully replace 2 with 1, 3 with 2, 4 with 3, etc. in the quoted string, it will return Mon=1 and Sun=7 as you desire...

And for month names "Jan-December" (3 letters necessary) into 1 to 12. Again, this is a "hash function" and other words can/will result in "false positives" that must be confirmed against only one proper month name string.

int monthOrd( char cp[] ) { return "DIE@CB@LJF@HAG@K"[ cp[1]/4&7 ^ cp[2]*2 &0xF ] &0xF; }

Give it a play and let us know if it helps you get where you want to be.

EDIT:

Demonstrating functionality, here is an example that satisfies the OP question. The LUT values have been adjusted so that "Mon(day)" is day 1.

This does the conversion (trusting the source string) without invoking sprintf(). Here, printf() is used for 'diagnostic testing' only.

static int monthOrd( char cp[] ) { return "DIE@CB@LJF@HAG@K"[ cp[1]/4&7 ^ cp[2]*2 &0xF ] &0xF; }
static int wkdayOrd( char cp[] ) { return "54072316"[*cp/2 + ~cp[1] & 0x7] & 0x7; }

static char *toDigitStr( int val ) { // multiple execution overwrites result
    static char buf[3];
    buf[0] = (char)('0' + val/10);
    buf[1] = (char)('0' + val%10);
    buf[2] = '\0';
    return buf;
}

int main() {
    char *dayName = "Mon";
    printf( "%s ==> %s\n", dayName, toDigitStr( wkdayOrd( dayName ) ) );

    char *mthName = "Aug";
    printf( "%s ==> %s\n", mthName, toDigitStr( monthOrd( mthName ) ) );

    mthName = "DECEMBER";
    printf( "%s ==> %s\n", mthName, toDigitStr( monthOrd( mthName ) ) );

    return 0;
}

Output:

Mon ==> 01
Aug ==> 08
DECEMBER ==> 12
0
chux - Reinstate Monica On

... how to assign an integer value to an array of string (?)

time_array[] is not an array of strings. It is an array of pointers to strings. This distinction is important as string lifetimes need careful consideration. Here, the strings pointed to by time_array[i] are not certainty modifiable.

char *time_array[7] = {"45", "55", "11", "Mon", "29", "Aug", "2022"};

We could change the pointer by re-assigning a compound literal. It is easy to form a an integer like string with single digit values like 1-7. Yet the lifetime of the compound literal only lasts to the end of the block of code.

int day_index = 1;
time_array[3] = (char[3]){ '0', '0' + day_index, '\0'}; // , '\0' optional as rest is zero filled
// good for a while

Or perhaps make time_array[] an array of strings and then re-assign the indexed string.

char time_array[7][5] = {"45", "55", "11", "Mon", "29", "Aug", "2022"};
int day_index = 1;
strcpy(time_array[3], (char[3]){ '0', '0' + day_index });
// or
snprintf(time_array[3], sizeof time_array[3], "%02d", day_index);


// good indefinitely