代码之家  ›  专栏  ›  技术社区  ›  Jung Jaehoon

如何使用一个简单的语句来描述关于C中函数“sprintf”的重复格式说明符?

  •  2
  • Jung Jaehoon  · 技术社区  · 6 年前

    下面是我的代码。我想提高效率。 有那么多格式说明符是相同的。 也有类似的目标属于一个数组。

    我的问题是…

    1. 如何减少重复的格式说明符的数量?
    2. 如何使用目标的一般表达式(double[i])?

    谢谢你的帮助。

    char * msg = sprintf("%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
                                 intnum,       doublenum[0],  doublenum[1],
                                 doublenum[2], doublenum[3],  doublenum[4],
                                 doublenum[5], doublenum[6],  doublenum[7],
                                 doublenum[8], doublenum[9],  doublenum[10]);
    
    4 回复  |  直到 6 年前
        1
  •  4
  •   jgb    6 年前

    首先需要提供足够大的缓冲区来写入。签字 sprintf

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

    它返回写入缓冲区的字符数 str .

    您可以捕获该值以将指针调整到 STR 用到目前为止所写的字符数来抵消。

    如果没有任何错误检查和缓冲区溢出保护,它可能看起来像这样:

    char msg[BUFSZ];
    int msgl = sprintf(msg, "%d", integer);
    for(int i = 0; i < 10; ++i)
    {
        msgl += sprintf(msg + msgl, " %lf", ds[i]);
    }
    

    对于一些足够大的 BUFSZ .

        2
  •  2
  •   Jonathan Leffler    6 年前

    简单的 example 将是:

    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
    
        char msg[100]; 
        int x=1, i=0;
        double d[10]; 
        for(i=0; i<10; i++)
            d[i] = i+10.0;
        sprintf(msg, "%d", x); 
        for(i =0; i<10; i++){
            sprintf(msg + strlen(msg), " %lf", d[i]);
        }
    
        printf("%s\n", msg);
        return 0;
    }
    
        3
  •  2
  •   Jonathan Leffler    6 年前

    您的最佳选择可能是沿着这些行编码:

    double array[10] = { 25.66, 87.51, 38.53, 26.59, 85.54, 47.82, 69.68, 27.79, 21.98, 12.80, };
    enum { NUM_ARRAY = sizeof(array) / sizeof(array[0]) };
    char buffer[1024];
    int integer = 3141592;
    
    int offset = 0;
    int nbytes = snprintf(buffer + offset, sizeof(buffer) - offset, "%d", integer);
    if (nbytes < 0) { …report error and stop processing… }
    offset += nbytes;
    for (int i = 0; i < NUM_ARRAY; i++)
    {
        nbytes = snprintf(buffer + offset, sizeof(buffer) - offset, " %lf", array[i]);
        if (nbytes < 0) { …report error and stop processing… }
        offset += nbytes;
    }
    

    严格来说,代码应该检查 nbytes >= sizeof(buffer) - offset 以确保没有截断。

    你是否认为这更简单是另一回事。然而,它比原来的要灵活得多(或有潜力变得更灵活)。如果您只需要打印8,或者打印一些大量的值,那么(在函数中使用适当的包装),您可以处理所有变量。您可以使用各种其他技巧,例如确保输出行不超过N个字节,插入换行符,或者使用一些前导填充。天空是极限。

        4
  •  1
  •   Sir Jo Black    6 年前

    我编写了这个简单的示例代码,它从命令行读取参数并将它们插入变量中 msg .

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[]) {
        char msg[2000];
        int msgl;
        int x,i,n;
        double d[10];
    
        //    Load values from command line
        // -----------------------------------------
        if (argc>12 || argc<3) {
            puts("Usage: prgname ni nd1 {nd2,nd3 ..., nd10}\n");
            return 1;
        }
    
        n=argc-2; // number of double values
    
        x=atoi(argv[1]);
        for(i=0;i<n;i++)
            d[i]=strtod(argv[i+2],NULL);
        // -------------------------------------------
    
        // -------------------------------------------
        //     THE ALGORITHM SOLVING THE QUESTION
        // -------------------------------------------
        *msg=0;     // clear msg
        msgl = sprintf(msg,"%d",x);
    
        for(i=0;i<n;i++)
            msgl += sprintf(msg + msgl," %lf", d[i]);
        // -------------------------------------------
    
        puts(msg);
        return 0;
    }