Jeżeli C++ to można spróbować opcji z variadic templates
.
#include <iostream>
using namespace std;
enum class Type { INT , DOUBLE , STRING };
struct Arg
{
Arg(int value) : type(Type::INT) { int_value = value; }
Arg(double value) : type(Type::DOUBLE) { dbl_value = value; }
Arg(const char *value) : type(Type::STRING) { str_value = value; }
Type type;
union {
int int_value;
double dbl_value;
const char *str_value;
};
};
string getValue( Type type , const Arg& arg )
{
if( type != arg.type ) return "";
if( arg.type == Type::INT ) return to_string(arg.int_value);
else if( arg.type == Type::DOUBLE ) return to_string(arg.dbl_value);
else if( arg.type == Type::STRING ) return arg.str_value;
}
void implement_my_printf( string text , const Arg *args , size_t argsize )
{
int argcount {0};
string result;
for( size_t index=0 ; index<text.size() ; ++index )
{
if( text[index] == '%' && argcount != argsize )
{
if( ++index == text.size() ) break;
switch( text[index] )
{
case 'd': result += getValue(Type::INT,args[argcount++]); break;
case 'f': result += getValue(Type::DOUBLE,args[argcount++]); break;
case 's': result += getValue(Type::STRING,args[argcount++]); break;
}
}
else result += text[index];
}
cout << result;
}
template <typename... Args>
void my_printf( string text , const Args&... args )
{
Arg arg_array[] = {args...};
implement_my_printf( text , arg_array , sizeof...(Args) );
}
int main()
{
my_printf( "number1 %d number2 %d number3 %d double %f string %s end" , 2 , -4 , 4 , 45.6 , "test");
return 0;
}