代码之家  ›  专栏  ›  技术社区  ›  Yanick Rochon

C:printf中的sprintf作为第一个参数

  •  3
  • Yanick Rochon  · 技术社区  · 15 年前

    在大学里学C。这不是家庭作业,但我想做点什么(作业中的“创造性”部分),结果被卡住了。

    我知道这是可能的

    printf("%d\n", printf("23.4")); // -> 23.44 (i.e. 23.4 + 4 bytes written)
    

    但是我怎么用 sprintf() 作为第一个论点 printf() ?

    类似于:

    char * getFormatString(int n) {
       char * buffer;
    
       sprintf(buffer, "Value with %%d decimals is %%.%df", n);
    
       return buffer; 
    }
    
    void foo() {
       int decimals = 2;
       float pi = 3.141592;
    
       printf(getFormatString(decimals), decimals, pi);  // should output "Value with 2 decimals is 3.14"
    }
    

    这可能吗?到目前为止,我在执行时遇到了seg错误。

    5 回复  |  直到 15 年前
        1
  •  6
  •   R.. GitHub STOP HELPING ICE    15 年前

    使用 sprintf 为此目的是不正当的。相反,请尝试:

    printf("Value with %d decimals is %.*f", decimals, decimals, pi);
    
        2
  •  2
  •   SirDarius    15 年前

    您至少应该先为缓冲区分配内存(并在最后释放它):

    char * buffer;
    int decimals = 2;
    float pi = 3.141592;
    
    buffer = (char *) malloc(256); /* big enough buffer */
    sprintf(buffer, "Value with %%d decimals is %%.%df", decimals);
    printf(buffer, decimals, pi);
    
    free(buffer);
    
        3
  •  2
  •   paleozogt    15 年前

    printf 返回打印的字符数,因此第一个示例实际上是

    printf("%d", printf("23.4")); // -> 23.44
    

    sprintf还返回打印的字符数,因此将其作为printf的参数可能不是您想要的。

    seg faulting的原因是缓冲区字符串没有指向任何内容。您要将代码更改为以下内容:

    char buffer[1024];    // buffer has to be an actual string (or you could use malloc)
    int decimals = 2;
    float pi = 3.141592;
    
    sprintf(buffer, "Value with %%d decimals is %%.%df", decimals);
    
    printf(buffer, decimals, pi);
    
        4
  •  1
  •   Michał Trybus    15 年前

    你被判了赛格法特,因为 sprintf 将数据写入内存中由垃圾指向的某个位置(在指针中 buffer ). 您需要使用malloc分配一些内存,例如:

    buffer = malloc(100);
    

    在函数中使用sprintf之前 getFormatString . 然后,记住在使用字符串后释放此内存。在这个特定的代码中存在内存泄漏,因为您不存储从 获取格式字符串 任何地方。

    更正代码:

    char *getFormatString(int n) {
        char *buffer = malloc(100);
        sprintf(buffer, "Value with %%d decimals is %%.%df", n);
        return buffer;
    }
    
    void foo() {
        int decimals = 2;
        float pi = 3.141592;
        char *fmtstr = getFormatString(decimals);
        printf(fmtstr, decimals, pi);  // should output "Value with 2 decimals is 3.14"
        free(fmtstr);
    }
    
        5
  •  0
  •   Ruel    15 年前

    printf() sprintf() 两者都返回一个 int 价值。它是字符总数。

    int sprintf ( char * str, const char * format, ... );
    int printf ( const char * format, ... );
    

    你只能使用 冲刺() 作为一个论点 打印() 如果要打印由 冲刺() .