Boost has a class that implements type security Format, but the class is large, and it is more complicated, it is not very habit.
So it is still a simple implementation.
Let's take a look at the needs:
Format_String.Format ("[%] =%")% a% strname
In fact, it is to replace the two% of the format string "[%] =%" in the back of the A and STRNAME, which is equivalent to:
StringStream Format_String; Format_String << "[" << a << "=" << Strname;
Of course, to be universal, but I hope that it is possible to output to StringStream, it is best to be output to std :: ostream. Class Format_Stream {public: explicit format_stream (std :: ostream& outs): m_output (outs), m_lpszformat (& g_nendflags) {}
inline format_stream & format (const char * lpszFormat) {flushFormat (); m_lpszFormat = lpszFormat; return outputPrefix ();} template
~ Format_stream (void) {} protected: inline std :: ostream & getOutput (void) {return m_output;} void flushFormat (void) {if (* m_lpszFormat) {getOutput () << m_lpszFormat; m_lpszFormat = & g_nEndFlags;}} format_stream & outputPrefixLoop (void); format_stream & outputPrefix (void); static char g_nEndFlags; std :: ostream & m_output; const char * m_lpszFormat;}; char format_stream :: g_nEndFlags = char ();
format_stream & format_stream :: outputPrefix (void) {char * lpPos = strchr (m_lpszFormat, '%'); if (lpPos = NULL!) {getOutput () write (m_lpszFormat, lpPos - m_lpszFormat);. m_lpszFormat = lpPos 1; IF (* m_lpszformat == '%' && * (m_lpsster 1)! = ') return outputputprefixloop ();} // if (lppos! = null) else flushformat (); return * this;} format_stream & format_stream :: OutputPrefixloop (void) {While (* m_lpszformat == ') {char * lppos = strchr (m_lpszformat 1,'% '); if (lppos! = null) {getOutput (). Write (m_lpszformat, lppos - m_lpszformat; m_lpszformat = lppos 1; if (* m_lpsformation! = '%' || * (m_lpszformat 1) == '%') Break;} // if (lppos! = null) ELSE {Flushformat (); break;}} // while (* m_lpszformat) return * this;}
1. The position indicates the replacement of the subsequent variable by '%' as a placeholder. 2, two consecutive '%', '%%' means a real '%'. However, it is necessary to pay attention to: When you want to output a percentage, you have to write %%%. If the analyst discovers three consecutive '%', it is considered that the first is a placeholder, and then two represents a '%'. When you find four '%', the first two will be considered placeholders, and the last two are considered to be a '%'. 3, Boost uses% to connect multiple variables behind, and some libraries use commas. Individuals are not very like: '%' It is too much, and the program looks unrestrained; many books are still better not to overload comma operators. So, use the function to be relatively stable, so use the function arg (a) form. If you really like using the '%' or a comma, only need to add member function: template
Soapyr-formatted output parameters written in the format string, I always remember, once the wrong program is prone to problems (not only displayed, it may beDUMP), and discover different platform formats There will be some different. Still written in Arg is relatively stable, and the program is easy to read.
In order to distinguish between the function of "the same placeholder output multiple variables", it still takes another function name: enum int_base {base10 = std :: os :: dec, base8 = std :: os :: c = std :: os :: 动, base16 = std :: hex ios ::}; enum CHAR_CASE {CHAR_UPCASE = 0, CHAR_LOWCASE = 1}; enum BASE_FLAG {HIDE_BASE = 0, SHOW_BASE = 1}; enum POS_FLAG {HIDE_POS = 0, SHOW_POS = 1}; enum FIX_FLAG {FIXED = 0, SCIENTIFIC = 1}; enum POINT_FLAG {HIDE_POINT = 0, SHOW_POINT = 1}; enum ADJUSTFIELD_FLAG {ADJUST_LEFT = std :: ios :: left, ADJUST_RIGHT = std :: ios :: right, ADJUST_INTERNAL = std :: ios :: internal}; template