Variable format specifier in C

I have a printf statement as follows:

printf("[%d] %d", i, n->data);

I'm trying to make the related code flexible so you can change the variable type of "n->data" depending on your need. Is there a way to make the format specifier update depending on the variable type used?

I've tried including:

const char FS[2] = "%f";

when the variable is a float, then amending the printf statement to:

printf("[%d] "FS, i, n->data);

but this gets the following error, which I don't know how to resolve:

dLList.c:125:23: error: expected ')'
        printf("[%d] "FS, i, n->data);
                      ^
dLList.c:125:15: note: to match this '('
        printf("[%d] "FS, i, n->data);
              ^
1 error generated.

Any ideas? Thanks


Instead of const char FS[2] = "%f"; , you may try to use macro like this:

#define FS "%f"

that would aggregate the control string format as you apparently want.


Is there a way to make the format specifier update depending on the variable type used?

Yes, C11 has _Generic . This allows code selection based on the type of the expression. The selection is not evaluated at run-time, but at compile time, the type is determined.

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

#define print(X) printf(_Generic((X), 
    double: "%en", 
    int: "%in", 
    char *: "%sn", 
    default: "TBD" 
) , X)

int main(void) {
  print(5.0);
  print(5);
  print("Five");
  print(1.0f);
  return 0;
}

Output

5.000000e+00
5
Five
TBD

You could use an enum and a lookup table for format strings. Just make sure your struct that contains the data also contains a matching enum describing the type of data currently contained in the struct.

That way you can write a print function that accepts such a struct as an argument and prints its value using a correct format string for that type of data.

#include <stdio.h>

typedef enum Format_
{
    /* Add/remove formats as needed. */
    SIGNED_DECIMAL_INT,
    UNSIGNED_DECIMAL_INT,
    DECIMAL_FLOATING_POINT,
    STRING,
    POINTER_ADDRESS,
    NUM_SUPPORTED_FORMATS
} Format;

static const char* formatStrings[NUM_SUPPORTED_FORMATS] =
{
    "%dn", /* Add more complex format strings if needed. */
    "%un",
    "%fn",
    "%sn",
    "%pn"
};

typedef struct Wrapper_
{
    Format format;
    float data;
} Wrapper;

void printData(const Wrapper *const wrapper)
{
    printf(formatStrings[wrapper->format], wrapper->data);
}

int main(void)
{
    Wrapper wrapper;

    wrapper.format = DECIMAL_FLOATING_POINT;
    wrapper.data = 12.345f;

    /* Prints 12.345000 */
    printData(&wrapper);

    return 0;
}
链接地址: http://www.djcxy.com/p/90304.html

上一篇: 在程序输出中出现下溢

下一篇: C中的变量格式说明符