如何用简单的语句来描述C语言中关于函数'sprintf'的重复格式说明符?

how to use a simple statement to describe repeated format specifiers about function 'sprintf' in C?

下面是我的代码。我想让它更有效率。 有很多相同的格式说明符。 还有类似的目标属于一个数组。

我的问题是...

  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]);

一个简单的 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;
}

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

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

它returns写入缓冲区的字符数量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

你最好的选择可能是按照这些行编写代码:

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 个字节、插入换行符和可能的一些前导填充。天空是极限。

我写了这个简单的示例代码,它从命令行读取参数并将它们插入变量 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;
}