printf %.*s 原来是这样

        今天看代码时,看到这样一个printf,以前没见过这样的,也没这样用过,一下子还真不知道是什么意思:

// Response is received. Print it
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
printf("%.*s", (int) hm->message.len, hm->message.ptr);
c->is_closing = 1;         // Tell mongoose to close this connection
*(bool *) fn_data = true;  // Tell event loop to stop

printf("%.*s", (int) hm->message.len, hm->message.ptr); 最常用的就是用 %s 打印字符串了,看到这个懵了。刚好 mongoose 源码有一个类似的函数:

void mg_log(const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
  va_end(ap);
  logc((unsigned char) '\n');
}

主要看 mg_vxprintf() 这个函数的实现,它的用法是这样的:

MG_INFO(("%.*s %.*s %.*s %.*s", (int) hm->method.len, hm->method.ptr,
			(int) hm->uri.len, hm->uri.ptr, (int) tmp.uri.len, tmp.uri.ptr,
			(int) cl->len, cl->ptr));

看完源码后才明白,原来 %.* 是限制长度(精度)的。下面看一个例子:

#include 
#include 

int main()
{
    double temperature = 20.3456;
    char strTemp[32] = {0};
    snprintf(strTemp, sizeof(strTemp), "%.3f", temperature);
    printf("strTemp = %s\n", strTemp);

    return 0;
}

如果我们需要保留小数点后的几位小数,我们是这样用的:snprintf(strTemp, sizeof(strTemp), "%.3f", temperature); 这里面的 3 就表示保留3位小数点。

输出结果为:20.346,所以同样的 %.*s 中的 * 表示一个参数(int类型),这个参数放在参数列表里,如:

#include 
#include 

int main()
{
    double temperature = 20.3456;
    char strTemp[32] = {0};
    snprintf(strTemp, sizeof(strTemp), "%.3f", temperature);
    printf("strTemp = %.*s\n", 4, strTemp);

    return 0;
}

printf("strTemp = %.*s\n", 4, strTemp); 在原码里当遇到符号 * 时,它会去找参数列表,此时它取到的就是4,表明这个字符串只保留 4 个字符长度。

总结:%.* 表示要截取指定长度(精度), * 可以写成具体的数值,如:%.3f,如果直接写 *,则参数列表要有对应的数值,如参数列表中的 4 :printf("strTemp = %.*s\n", 4, strTemp);

 

你可能感兴趣的:(#,库函数,c++)