C++ format 格式化字符串实现方式

C++ format 格式化字符串实现方式

2018年04月23日 10:18:03 slitaz 阅读数 8088更多

分类专栏: C++11

1.

http://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf

You can't do it directly, because you don't have write access to the underlying buffer (until C++11; see Dietrich Epp's comment). You'll have to do it first in a c-string, then copy it into a std::string:

charbuff[100];

snprintf(buff, sizeof(buff),"%s","Hello");

std::stringbuffAsStdStr = buff;

But I'm not sure why you wouldn't just use a string stream? I'm assuming you have specific reasons to not just do this:

  std::ostringstream stringStream;

stringStream <<"Hello";

std::stringcopyOfStr = stringStream.str();

2.

https://www.zhihu.com/question/35967887/answer/125238385

3.

boost::format

4.

http://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf

Emphasising C++11std::snprintf, this becomes a pretty easyandsafe task. I see a lotofanswersonthis question that were apparently written before the timeofC++11whichusefixed buffer lengthsandvargs, something I wouldnotrecommendforsafety, efficiencyandclarity reasons.

#include <memory>

#include <iostream>

#include

#include <cstdio>

usingnamespacestd;//Don't if you're in a header-file

template<typename ... Args>

stringstring_format(conststd::string& format, Args ... args )

{

    size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'

unique_ptr buf(new char[ size ] );

    snprintf( buf.get(), size, format.c_str(), args ... );

    return string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside

}

Line by line explanation:

Aim:Writetoa char* by using  std::snprintfandthenconvert thattoa std::string.

First, we determine the desired lengthofthe chararray.

From cppreference.com:

Return value

[...]Ifthe resultingstringgets truncated duetobuf_size limit,functionreturnsthetotalnumberofcharacters(notincluding the terminatingnull-byte)whichwouldhavebeenwritten,ifthelimitwasnotimposed.

Thismeansthatthedesiredsizeisthenumberofcharactersplusone,sothatthenull-terminatorwillsitafterallothercharactersandthatitcanbecutoffbythestringconstructoragain.Thisissuewasexplainedby@alexk7inthecomments.

Then,weallocateanewcharacterarrayandassignittoastd::unique_ptr. Thisisgenerally advised,asyou won't have to manually delete it again.

Note that this is not a safe way to allocate a unique_ptr with user-defined types as you can not deallocate the memory if the constructor throws an exception!

After that, we can of course just use snprintf for its intended use and write the formatted string to the char[] and afterwards create and return a new std::string from that.

You can see an example in action here.

Additional information for Visual Studio users:

As explained in this answer, Microsoft renamed std::snprintf to _snprintf (yes, without std::). MS further set it as deprecated and advises to use _snprintf_s instead, however _snprintf_s won't accept the buffertobe zeroorsmaller than the formatted outputandwillnotcalculate the outputs lengthifthat occurs. Soinordertoget ridofthe deprecation warnings during compilation, you can insert the following line at the topofthefilewhich contains theuseof_snprintf:

#pragma warning(disable :4996)

5.

https://github.com/fmtlib/fmt#compile-time-and-code-bloat

fmt is an open-source formatting library for C++. It can be used as a safe alternative to printf or as a fast alternative to IOStreams.

6.

https://github.com/c42f/tinyformat

tinyformat.h is a type safe printf replacement library in a single C++ header file. If you've ever wanted printf("%s", s) to just work regardless of the type of s, tinyformat might be for you. Design goals include:

Type safety and extensibility for user defined types.

C99 printf() compatibility, to the extent possible using std::ostream

Simplicity and minimalism. A single header file to include and distribute with your projects.

Augment rather than replace the standard stream formatting mechanism

C++98 support, with optional C++11 niceties

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容