0

I'm trying to do something like a dictionary for c. I want that different types of data to be stored in a dictionary. In order to get an unlimited number of values, I used stdarg.h but got a problem with determining the data type. I have a few questions:

How can I determine the data type of each element?

How can I create a loop that will work until the elements are over?

For example this code from K&R

include <stdarg.h>
/* minprintf: минимальный printf с переменным числом аргумент */
void minprintf(char *fmt, ...)
{
    va_list ар; /* указывает на очередной безымянный аргумент */
    char *p, *sval;
    int ival;
    double dval;
    va_start(ap, fmt); /* устанавливает ар на 1-й безымянный аргумент */
    for (p = fmt; *р; р++) {
        if (*p != '%') {
            putchar(*p);
            continue;
        }
        switch (*++р) {
        case 'd':
            ival = va_arg(ap, int);
            printf ("%d", ival);
            break;
        case 'f':
            dval = va_arg(ap, double);
            printf("%f", dval);
            break;
        case 's':
            for (sval = va_arg(ap, char *); *sval; sval++)
            putchar(*sval);
            break;
        default:
            putchar(*p);
            break;
        }
    }
    va_end(ap); /* очистка, когда все сделано */
}

And here fmt is string that contains quantity elements.

But how can I write a function that doesn't contains this string?

For example:

#include <stdio.h>
#include <stdarg.h>

void test (const char *, ...);

int main ()
{
    test("Hello", "world", 15, 16.000);

    return 0;
}

Thanks a lot for taking your time.

Gari
  • 183
  • 7

2 Answers2

3

You cannot.

C simply doesn't provide any way for a variadic function to independently detect the types of arguments that were passed, nor the number of them. So you have to design your function such that it can work this out from other information provided by the caller.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
1

You can.

Since C99,

How can I determine the data type of each element?

Use _Generic

How can I create a loop that will work until the elements are over?

See below


Change the call to use a macro GARI(obj)

// test("Hello", "world", 15, 16.000);
test(GARI("Hello"), GARI("world"), GARI(15), GARI(16.000), 0);

GARI is a macro the uses _Generic to distinguish types and provide an enumerator. Then 2 arguments to test are passed: an enumerator to ID the type and then the object itself.

This obliges _Generic to enumerate many types. There are infinite numbers of possible types, but a basic list _Bool, char, long long, double, char *, etc. is reasonable.

Then test() uses the enumeration to steer selection of the next argument. Recommend a 0 to end the list.


This is all not a simple coding nor something for a learner.

"example this code from K&R" --> C have evolved in 40+ years. Consider newer references.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256