观察:可变参数的格式化输出
本文描述了将可变参数(variadic)按照格式化字符串的方式输出至标准输出(stdout)或文件流(ofstream)的
博客园 2023-05-11 15:34:32
本文描述了将可变参数(variadic)按照格式化字符串的方式输出至标准输出(stdout)或文件流(ofstream)的一种实现方案,并加以了验证。
通过可变参数函数(variadic function)和可变参数模板(variadic template),能够接受个数不定的参数。两种接受参数方式与两种输出目的地的组合,可以得到四种情况,
(资料图)
结合 *printf 系列输出函数以及变参标准库(
以下代码片段(variadic_printf.cpp)展示了此实现方案,
可变参数函数输出至标准输出(A),
static void A(const char* fmt, ...){ std::va_list args; // #1 va_start(args, fmt); std::vfprintf(stdout, fmt, args); // #2 // or // std::vprintf(fmt, args); va_end(args);}
使用 std::va_list 对象与 va_start (#1)访问可变参数;然后由 std::vfprintf() 或 std::vprintf() 函数将可变参数输出(#2)至标准输出;最后用 va_end 宏结束对可变参数的访问。
可变参数模板输出至标准输出(B),
template static void C(const char* fmt, const Types&... args){ std::fprintf(stdout, fmt, args...); // #3 // or // std::printf(fmt, args...);}
直接由 std::fprintf() 或 std::printf() 函数输出(#3)。
可变参数函数输出至文件流(C),
static void C(const char* fmt, ...){ std::va_list args, copied; va_start(args, fmt); va_copy(copied, args); // #4 char* buffer = new char[std::vsnprintf(nullptr, 0, fmt, copied) + 1]; // +1 for "\0" std::vsprintf(buffer, fmt, args); // #5 stream << buffer; delete[] buffer; va_end(copied); va_end(args);}
使用 std::va_list 对象与 va_start 访问可变参数;可变参数的一份拷贝用于 std::vsnprintf() 函数计算待输出字符串的长度,并依此长度开辟存放字符串的临时空间(#4);再由 std::vsprintf() 函数将可变参数输出至临时空间中(#5),紧接着输出至文件流;最后释放临时空间并结束对可变参数的访问。
可变参数模板输出至文件流(D),
template static void D(const char* fmt, const Types&... args){ char* buffer = new char[std::snprintf(nullptr, 0, fmt, args...) + 1]; // +1 for "\0" std::sprintf(buffer, fmt, args...); // #6 stream << buffer; delete[] buffer;}
std::snprintf() 函数计算待输出字符串的长度,并依此长度开辟存放字符串的临时空间;然后由 std::sprintf() 函数将可变参数输出至临时空间中(#6),紧接着输出至文件流;最后释放临时空间。
以下是这四个函数的测试用例,
... A("\n%s won the %2dth FIFA World Cup!\n", "Argentina", 22);B("\n%s uses %13s to shoot the %d eagles.\n", "Bower", "Hoyt Highline", 2);C("\n%s is easy as pie!\n", "Cxx");D("\n%s counted the money again. %4.2f dollars. That was all.\n\n", "Della", 1.87);...
在命令行中编译代码(-std=c++11),运行可执行文件并检查输出结果。以下是输出结果的部分内容,
$ g++ -std=c++11 variadic_printf.cpp$ ./a.outArgentina won the 22th FIFA World Cup!Bower uses Hoyt Highline to shoot the 2 eagles.$ cat variadic.outputCxx is easy as pie!Della counted the money again. 1.87 dollars. That was all.$
完整的代码请参考 [gitee] cnblogs/17390064 。
写作过程中,笔者参考了 获取va_list格式化长度。致作者 sdhongjun 。
本文描述了将可变参数(variadic)按照格式化字符串的方式输出至标准输出(stdout)或文件流(ofstream)的
刑事谅解书本身并无固定格式,出具谅解书的目的是减轻犯罪嫌疑人处罚,有的可以对犯罪嫌疑人取保候审,所以
今天小编肥嘟来为大家解答以上的问题。驻站作品专属作品和授权作品,独家作品首发作品驻站作品分别是什么意
华创证券发布研究报告称,由于2022年锦欣生殖(01951)发布新的股权激励带来一次性开支、收并购带来的折旧摊
5月11日,“高质量发展调研行”主题采访活动启动,第一批次采访首站为上海。在当日举行的高质量发展调研行
高叶和张颂文互动网易娱乐5月11日报道狂飙夫妻的梦幻联动来啦!5月10日是张颂文生日,高叶微博送上祝福:生
近日,有网友发现,自己给孩子买的历史读物中出现事实性错误:在讲述甲午中日海战时,书中用了一张“丁汝昌
世界食品(深圳)博览会开幕发酵食品成为展会亮点---
5月11日陕西地区硝酸铵价格走势暂稳,场内商谈主流在5400-5500元 吨,场内装置运行稳定,近期上游原料市场
日前召开的二十届中央财经委员会第一次会议强调,坚持推动传统产业转型升级,不能当成“低端产业”简单退出
今日NBA季后赛东部半决赛G5,尼克斯在主场以112-103击败热火,系列赛比分来2-3。此役,双方替补得分悬殊很
14 5万元 吨!硅料价格大幅下跌!,国际能源网 光伏头条(PV-2005)获悉,5月10日,硅业分会公布本周硅料最
一、解决优先购买权争议问题的建议对于优先购买权产生纠纷的情况,建议是:如果提起诉讼的原告确系房屋的原
【 "重庆姐弟坠亡案 "二审宣判:父亲与女友共谋致子女死亡,死刑是否维持】两年多前,重庆市发生了一起姐弟
新进展!日本科学家发现“血管清道夫”,8周74名志愿者血栓改善,血栓,细胞,纳豆,溶栓,血管清道夫,心血管系统