今天看代码时,看到这样一个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 <stdio.h>
#include <stdlib.h>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 <stdio.h>
#include <stdlib.h>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);