代码之家  ›  专栏  ›  技术社区  ›  exebook

sprintf数组中指针的可变数目

  •  1
  • exebook  · 技术社区  · 7 年前
    void *buffer[10];
    int size = backtrace(buffer, 10);
    char cmd[1024];
    sprintf(cmd, "addr2line -f -p -e a.out %p %p %p %p %p %p %p %p %p %p",
        buffer[0],
        buffer[1],
        buffer[2],
        buffer[3],
        buffer[4],
        buffer[5],
        buffer[6],
        buffer[7],
        buffer[8],
        buffer[9],
    );
    

    我有这个代码,大部分时间都能用,但有时 size 小于 10 ,如何轻松打印 大小 数组中的指针 buffer ?

    3 回复  |  直到 7 年前
        1
  •  4
  •   Jean-François Fabre    7 年前

    如果在一个循环中格式化临时缓冲区中的指针(带前导空格),然后将其与命令前缀连接起来:

    int size = backtrace(buffer, 10);
    char cmd[1024] = "addr2line -f -p -e a.out";
    char buf[20]; // should be enough to hold pointer value
    int i;
    for (i = 0; i < size; i++)
    {
       sprintf(buf," %p",buffer[i]);
       // you could even check the size here in case cmd+buf overflows cmd size
       strcat(cmd,buf);
    }
    

    或者对于性能纯粹主义者,因为 strcat 每次计算长度时,我们可以使用 sprintf

    char cmd[1024] = "addr2line -f -p -e a.out";
    int i;
    char *current = cmd + strlen(cmd);
    for (i = 0; i < size; i++)
    {
       int nb_written = sprintf(current," %p",buffer[i]);
       if (current+nb_written > cmd+sizeof(cmd)) break;  // avoids buffer overflow
       current += nb_written;
    }
    
        2
  •  2
  •   wildplasser    7 年前

    使用循环。 sprintf() 返回写入字符数或-1:


    void *buffer[10];
    char cmd[1024];
    int size,idx;
    size_t pos, len;
    
    size = backtrace(buffer, 10);
    pos = sprintf(cmd, "addr2line -f -p -e a.out");
    for(idx=0 ; idx< size;idx++){
            len = sprintf(cmd+pos, " %p", buffer[idx] );
            if (len<0 || len+pos >= sizeof cmd) break;
            pos += len;
            }
    

    或者,如果你想尊重 cmd[] 使用 snprintf() :


    #include <stdio.h>
    int backtrace(void**, int);
    
    void joop(void)
    {
    
    void *buffer[10];
    char cmd[1024];
    int size,idx;
    size_t pos, len;
    
    size = backtrace(buffer, 10);
    pos= snprintf(cmd,sizeof cmd, "addr2line -f -p -e a.out");
    for(idx=0 ; idx < size; idx++){
            len = snprintf(cmd+pos, sizeof cmd - pos, " %p", buffer[idx] );
            if (len < 0 || len+pos >= sizeof cmd) break;
            pos += len;
            }
    }
    
        3
  •  1
  •   AnT stands with Russia    7 年前

    如果数组的最大大小显式限制为 10 ,只需稍加修改即可:只需在适当的位置修剪格式字符串

    void *buffer[10];
    int size = backtrace(buffer, 10);
    
    char format[] = "addr2line -f -p -e a.out %p %p %p %p %p %p %p %p %p %p";
    format[24 + size * 3] = '\0';
    
    char cmd[1024];
    sprintf(cmd, format,
        buffer[0],
        buffer[1],
        buffer[2],
        buffer[3],
        buffer[4],
        buffer[5],
        buffer[6],
        buffer[7],
        buffer[8],
        buffer[9]
    );
    

    向变量函数提供过多的变量参数并没有什么错。

    当然,插入的确切位置 '\0' 应该以更易于阅读和维护的方式计算,而不是像上面的例子那样使用“魔法常数”。