在运行时使用动态参数调用printf 我尝试在C++中为PrimTF编写包装器。当然我找到了va_列表,但不知道它如何适用于我,因为 不会直接调用包装器。稍后我将展示

在运行时使用动态参数调用printf 我尝试在C++中为PrimTF编写包装器。当然我找到了va_列表,但不知道它如何适用于我,因为 不会直接调用包装器。稍后我将展示,c++,C++,我解析一个脚本,该脚本包含一个参数数目未知的函数,如 ASTNode node(Token(PRINT, PRINT)); consume(PRINT); consume(LPAREN); node.make_child(variable()); // <-- formatstring (node.child[int]) while(current_token._type() != RPAREN) { consume(COMMA); node.make_child(vari

我解析一个脚本,该脚本包含一个参数数目未知的函数,如

ASTNode node(Token(PRINT, PRINT));
consume(PRINT);
consume(LPAREN);
node.make_child(variable()); // <-- formatstring (node.child[int])
while(current_token._type() != RPAREN) {
    consume(COMMA);
    node.make_child(variable()); // <-- the values to replace in formatstring (node.child[int++])
    i++; 
}
consume(RPAREN);
return node;

据我所知,您有一个给定的格式字符串和读取/解析参数

您有两个问题需要处理:处理格式和使用正确的参数类型

printf系列不支持与Qt相反的部分替换,例如,Qt允许QString%1%2。argHello导致QStringHello%2允许链接

因此,您必须手动解析完整格式字符串:

打印常规字符。 遇到%时,检索标志格式,除非它是%%,在这种情况下直接显示%

从标志格式切换到适当的转换,如

 // flagFormat would "simply" be %i, %010d, %4.2f or %+.0e
 switch (format_type) {
     case EFormatType::String: // %s
          printf(flagFormat, to_string(args[i]).c_str()); break;
     case EFormatType::Int: // %i, %d
          printf(flagFormat, to_int(args[i])); break;
     case EFormatType::String: // %f, %F, %e, %g, %
          printf(flagFormat, to_double(args[i])); break;
     // ...
 }
 ++i;

“在我看来,这对你的健康更有利。”贾伯沃基现在应该清楚了。如果没有,没关系。。内森,我不能安装boost@brunoiostreams是一个讨厌的东西,重载位移位运算符是一个坏主意。可能重复的可能重复的请,添加更改的解释这不会执行替换,它只打印出一个表示函数的字符串。在屏幕上,您将看到printfHello%d world%s、param1、param2,。。。我在phpNice起点中寻找类似call_user_func_数组的东西。我想在vsprintf的配合下,我会得到我预期的结果。
// Pseudocode
out("printf(");
out($myformatstring);
int i = 1;
while(i<parameter_count) {
    out(parameter[i++]);
    out(",");
}
out(")");
// Pseudocode
// I would like to propose a way to solve the problem, added some stuff here

out("printf("); 

// you should create format string in accordance with types of parameters
$myformatstring = ""   // let suppose  myformatstring is of type "string"
                   // and it has defined operator "+=" (concatenation of strings)
for(int j = 0;j < parametar_count; j++)
{
    switch(parametar[j].type )  // suppose that you have type information of param's 
    {
        case 'i': myformatstring += " %d "; break;
        case 'f': myformatstring += " %f "; break;
        case 's': myformatstring += " %s"; break;
    ...  // you should handle all types you use ...

    }
}
$myformatstring += "\\n\","; // terminate format string and write a comma before 
                             // other arguments...
out($myformatstring);

int i = 1;
while(i<parameter_count) {
   out(parameter[i++]);
   if( i < parameter_count -1 )   // you don't need comma after last parameter 
      out(",");
}
out(");");
 // flagFormat would "simply" be %i, %010d, %4.2f or %+.0e
 switch (format_type) {
     case EFormatType::String: // %s
          printf(flagFormat, to_string(args[i]).c_str()); break;
     case EFormatType::Int: // %i, %d
          printf(flagFormat, to_int(args[i])); break;
     case EFormatType::String: // %f, %F, %e, %g, %
          printf(flagFormat, to_double(args[i])); break;
     // ...
 }
 ++i;
/* 
  there is example that explains how to use stdarg for a function 
  with variable number of parameters
*/ 



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

void myfunc(char* fmt, ...);

/* this example folows logic of printf to specify format
    %d - integer
    %c - single character
    %s - string
    other character will be copied to output
*/

int main( int argc, char* argv[])
{
    myfunc("%s %d ABCD %c", "a string", 4, 'D'); 
}


void myfunc(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;

  va_start(ap, fmt);
  while (*fmt)
  {
    if(*fmt == '%')
    { 
       fmt++;
       switch (*fmt)     // detect format characters
       {
         case 's':              /* string format character is recognized*/
             s = va_arg(ap, char *);
             printf("string: %s\n", s);  /* this example just print out paramater, you can do what you want */
         break;

         case 'd':              /* integer format character */
             d = va_arg(ap, int);
             printf("int: %d\n", d);
         break;

         case 'c':              /* char format character*/
            c = (char) va_arg(ap, int);
            printf("char: %c\n", c);
         break;

     default:
       printf("Just copy non format characters %c\n",*fmt);  // copy non format characters after %
       } 
     }
     else
       printf("just copy '%c'\n", *fmt); 

    fmt++;
  }
  va_end(ap);
}