This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

使用printf类的函数,怎么才能最下资源开销下,获得格式化字符的长度。



首先:我知道printf以及许多的printf类的函数都返回格式化后的字符长度。但是前提条件:
1.不占用实际内存
2.不使用NULL指针。

原因是使用G2553,硬件的内存非常有限,希望做到最小的系统内存开销。
printf函数已经用在它处,不能再使用了。
sprintf和vsprintf会造成已经数组的浪费。
并且IAR编译器中,使用NULL指针会造成系统崩溃(编译器并没有处理好NULL地址)。
如:char len = sprintf(NULL, "Hello world! %f\r\n", 3.14);会导致系统崩溃。
  
想问一下大家,有没有合适的函数可以用最小系统开销, 计算出格式化字符的最终长度。

比如(“hello world %02d”, 5)得到的结果应该是"hello world 05",长度应为14。

  • 你好,

    可以使用一个GPIO外加一个delay函数,模拟串口发送的波特率。

    这样可以在不占太多的软件资源输出log日志。

  • 哦,不是这个意思的。

    后来我倒是找到一个方法:

    使用C99 引入的 snprintf 函数,这样目标地址就可以是NULL,而不必担心影响系统安全。具体是:

    unsigned char len = snprintf(NULL, 0, format, ...);

    这样就只是返回格式化之后的长度。

    但是我又遇到了一个问题,是关于malloc函数的。出现了申请不到的问题。具体是自己做了一个类似于printf的函数:

    int my_printf(const char *format, ...)  {
         char * p_buffer;
         va_list vl;
         va_start(vl, format);
         unsigned char len = vsnprintf((char *)NULL, 0, format, vl);
         p_buffer = (char *)malloc(len);
         if (p_buffer == NULL)
             return -1;
         vsprintf(p_buffer, format, vl);
         va_end(vl);
         // ...
         将P_buffer中的内容输出至某设备(阻塞)
         // ...
         free(P_buffer);
    }

    这个函数正是应用了前面提到的,先计算出格式化字符的长度,然后用malloc动态申请处相应长度的空间,将格式化的字符放在其中,然后从串口中一次将其输出。但是出现了问题:

    主程序A(单行,完全正确):
    my_printf("12345678\r\n");
      
    主程序B(不断循环输出,完全正确):
    while(1)
         my_printf("12345678\r\n");
      
    主程序C(顺序执行,靠后面的申请不到空间,而且好像有规律。)
         my_printf("1234567\r\n");----成功
         my_printf("1234567\r\n");----成功
         my_printf("123456\r\n");----成功
         my_printf("12345\r\n");----成功
         my_printf("1234\r\n");----成功
         my_printf("12345\r\n");----成功
         my_printf("123456\r\n");----成功
         my_printf("1234567\r\n");----失败
         my_printf("12345678\r\n");----失败
         my_printf("123456789\r\n");----失败
         my_printf("12345678\r\n");----失败
         my_printf("1234567\r\n");----失败
         my_printf("123456\r\n");----成功
         my_printf("12345\r\n");----成功
         my_printf("1234\r\n");----成功
         my_printf("12345\r\n");----成功
         my_printf("123456\r\n");----成功
         my_printf("1234567\r\n");----失败
         my_printf("12345678\r\n");----失败
         my_printf("123456789\r\n");----失败
      
    不知道怎么回事。好像是第一次申请长度n,能够成功,后面就无法再申请到比n大的空间了。