rsk82
rsk82

Reputation: 29387

how to determine how many arguments would be needed to fulfill fprint formatted string?

I mean strings like "(%d%%%d) some text %s , %d%% %x %o %#x %#o \n". The printf family of functions somehow know how many args they would need from this string so separate argument for it is not needed. Is this functionality provided in c/c++ in terms of a separate function so I could write my own printf-like functions ? (yes I put these percents intentionally to accent how complicated it could get, so it is not simple counting of percent characters)

Upvotes: 2

Views: 217

Answers (3)

Grady Player
Grady Player

Reputation: 14549

the printf family of functions only knows about one parameter, the first one...

It basically scans the string and each time it encounters a format specifier that it understands it pulls then next argument of that size from the argument list... this is an easily corruptible behavior. imagine:

printf("%i",someInt); // fine
printf("%i",someLong); // depending on endianness and sized
                       // of those types could be the high or low 32 bits(probably)
printf("%i %i",someInt); // depending on abi could crash, read a int sized chunk
                         // of stack, or a register that would correspond to that 
                         // parameter.

so inherently not safe..
you should pay attention to warnings and when writing portable code do things like:

size_t t = 5; //can be 32 or 64 bit depending on arch.
printf("%ull",(unsigned long long)t);

Edit. I guess I only half answered the question... you can define your own variadic functions, the following adds count number of params and returns the result.

int sumList(int count, ...);
int main(int argc, const char * argv[])
{   
    printf("the answer is: %i",sumList(4,1,2,3,4));
    return 0;
}
int sumList(int count, ...)
{
    va_list args;
    va_start(args, count);
    int sum = 0;
    for (int i = 0; i<count; i++) {
        sum += va_arg(args, int);
    }
    va_end(args);
    return sum;
}

Upvotes: 1

Peter Ruderman
Peter Ruderman

Reputation: 12485

No, there is no standard library function for parsing printf-style format strings. If you want to write your own string formatting function, then I strongly recommend against following the printf example. It's inherently unsafe for the reasons mentioned in the others answers. It also has problems with localization since word order changes in some languages. Personally, I would write a type-safe function using templates and copying the .NET style of format strings. (Actually, I did do that--it's a lot of work but also fun.)

Upvotes: 1

Griwes
Griwes

Reputation: 9029

The problem with printf family is that it is not safe, and it doesn't really know or care how many format elements are there in string or in argument list.

printf family uses something called "variadic functions"; only one parameter is named (format string) and others are taken from the stack, without respecting their type or size - their type is deduced from format string, which makes it type-unsafe, and finds how many arguments to use by iterating over the string and finding all formatting specifiers, which makes it argument-number-unsafe. You can write variadic functions; syntax is

void foo(...);

and later you can use those macros and types, although if you are using C++, you should use C++11's variadic templates instead of C variadic functions, as variadic templates are type safe - you don't loose type information anywhere, and with universal references (but not quite thanks them) they are more powerful than variadic functions.

Upvotes: 2

Related Questions