Simple type security Format output

xiaoxiao2021-03-06  41

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 inline format_stream & arg (const typeArg1 & val) {getOutput () << val; return outputPrefix ();

~ 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 inline format_stream & operator% (const typeArg1 & val) {return arg (val);} template inline format_stream & operator , (const type arg (val);} 4, arg can continue to extend, A, the same placeholder output multiple variables, only need to add more member functions: Template inline format_stream & arg (const typeArg1 & val1, const typeArg2 & val2) {getOutput () << val << val2; return outputPrefix ();} template inline format_stream & arg ( Const Typearg1 & Val1, Const Typearg2 & Val2, Const Typearg3 & Val3) {getOutput () << VAL1 << VAL2 << Val3; Return OutputPrefix ();}, for example, sometimes a range: stream.format ("Range1: % RANGE2:% "). arg (Lowerbou ND1, '-', Upperbound1); stream.arg (LowerBound2, '~', UpperBound2) B, formatted output.

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 format_stream & argWithFormat (typeInt nVal, INT_BASE nBase = BASE10, CHAR_CASE bUpcase = CHAR_UPCASE, POS_FLAG bShowPos = HIDE_POS, BASE_FLAG bShowBase = HIDE_BASE, Adjustfield_flag nadjust = adjust_left, int nwidth = -1, char chfill = ') {std :: os :: fmtflags nflags = getOutput (). Flags (); getOutput (). Setf ((std :: ios :: fmtflags) Nbase, std :: os :: basefield; if (bshowpos == show_pos) getOutput (). setf (std :: os :: showpos); else getoutput (). unsetf (std :: os :: showpos); if (bupcase == char_upcase) getOutput (). setf (std :: ios :: Uppercase);

转载请注明原文地址:https://www.9cbs.com/read-51348.html

New Post(0)