Home > Software design >  Is it possible to treat a format specifier as a variable?
Is it possible to treat a format specifier as a variable?

Time:11-14

I would like for this function to be able to return data from the given time_t argument according to the specifier argument.

If specifier is 'd', it should return the Day of the month (01-31);
If specifier is 'W', it should return the Week of the year (00-53).

int get_number_atr_from_time(time_t raw_time, char specifier) {
    struct tm *info = localtime(&raw_time);

    char buffer[3];
    strftime(buffer, 3, "%specifier", info);

    return atoi(buffer);
}

Can this somehow be done?

CodePudding user response:

Many (if not most) of the standard C functions that take a "format" argument, such as printf and – as in your code – strftime, take that argument as a const char*. However, that does not mean it has to be a string literal.

Any char array that you have declared and written-to yourself (i.e. not const) can still be passed as a const char* argument. So, you can write the required format specifier to a pre-declared format array and then pass that to the strftime function.

In the following code, I show how you can do this to get the current day-of-month and week-of-year, passing 'd' and 'W', respectively, to your function, which then writes that (together with the required % prefix) to the format string used for the strftime call.

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

int get_number_atr_from_time(time_t raw_time, char specifier)
{
    struct tm* info = localtime(&raw_time);
    char buffer[3];
    char format[3] = { '%', specifier, 0 }; // Initialize as "%X", where X is
    strftime(buffer, 3, format, info);      // "specifier" - and add null char
    return atoi(buffer);
}

int main(void)
{
    time_t tNow = time(NULL);
    int dy = get_number_atr_from_time(tNow, 'd');
    int wk = get_number_atr_from_time(tNow, 'W');
    printf("D = %d, W = %d\n", dy, wk);
    return 0;
}

Output as of the date of posting:

D = 13, W = 45

Note that there will be a number of more efficient ways to retrieve the day and week values from a time_t or struct tm value, but the above code shows how to solve your specific problem.

CodePudding user response:

Simply use compound literal:

strftime(buffer, 3, (char []){'%', specifier, 0}, info);
  • Related