青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

cyt
??? boost就有一個實現類型安全format的類,不過類比較龐大,而且也比較復雜,用起來也不是很習慣。
所以還是自己簡單實現一個了。
??? 先看看需求:format_string.format("[%] = %") % a % strName
??? 其實就是希望后面的a和strName分別替代格式化字符串"[%] = %"中的兩個%號,相當于:
??? stringstream format_string;
??? format_string << "[" << a << "] = " << strName;

??? 當然,要做到通用,還是希望不單能輸出到stringstream,最好還是能輸出到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_lpszFormat + 1) != '%')
??????????????????????? return outputPrefixLoop();
??????? } // 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_lpszFormat != '%' || *(m_lpszFormat + 1) == '%')
??????????????????????????????? break;
??????????????? } // if (lpPos != NULL)
??????????????? else
??????????????? {
??????????????????????? flushFormat();
??????????????????????? break;
??????????????? }
??????? } // while (*m_lpszFormat)
??????? return *this;
??? }

??? 1、規定以'%'作為占位符,表示后續的變量替換的位置。
???????
??? 2、兩個連續'%'即 '%%'表示一個真正的'%'。不過需要注意的是:一般想輸出百分數的時候,就是要寫%%%,
分析程序發現三個連續'%',則認為第一個是占位符,后兩個表示一個'%'。而發現四個'%'的時候,前兩個都會被認
為是占位符,最后兩個被認為是一個'%'。

??? 3、boost用%連接后面的多個變量,也有些類庫使用逗號。個人都不是很喜歡:'%'用得太多,程序看起來不好
看;很多書都再三聲明最好不要重載逗號運算符。所以還是使用函數比較穩妥,所以就用函數arg(a)的形式。如果真
的喜歡使用'%'或者逗號,只需要增加成員函數:
??????? template
??????????? inline format_stream & operator%(const typeArg1 & val) { return arg(val); }
??????? template
??????????? inline format_stream & operator,(const typeArg1 & val) { return arg(val); }
???????????????
??? 4、arg還可以繼續擴展,
??????? a、同一個占位符輸出多個變量,只需要增加多幾個成員函數:
??????? 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();
??????? }
??????? 例如有時候想輸出一個范圍:
???????
??????? stream.format("range1:% range2:%").arg(lowerbound1,'-',upperbound1);
??????? stream.arg(lowerbound2,'~',upperbound2)
???????
??????? b、格式化輸出。printf那么多的格式化輸出參數寫在格式化字符串中,我老是會記錯,一旦寫錯
??????? 程序就容易出問題了(不單是顯示錯誤,還有可能會coredump),另外發現不同平臺格式還會有
??????? 些不一樣。還是寫在arg里面比較穩妥,而且程序也容易閱讀。
???????
??????? 為了和上面"同一個占位符輸出多個變量"的函數區分,還是另外取一個函數名:
???????
??????? enum??? INT_BASE
??????????????? {BASE10=std::ios::dec, BASE8=std::ios::oct, BASE16=std::ios::hex};
??????? 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::ios::fmtflags nFlags = getOutput().flags();
??????????????? getOutput().setf((std::ios::fmtflags)nBase, std::ios::basefield);
??????????????? if (bShowPos == SHOW_POS)
??????????????????????? getOutput().setf(std::ios::showpos);
??????????????? else
??????????????????????? getOutput().unsetf(std::ios::showpos);
??????????????? if (bUpcase == CHAR_UPCASE)
??????????????????????? getOutput().setf(std::ios::uppercase);
??????????????? else
??????????????????????? getOutput().unsetf(std::ios::uppercase);
??????????????? if (bShowBase == SHOW_BASE)
??????????????????????? getOutput().setf(std::ios::showbase);
??????????????? else
??????????????????????? getOutput().unsetf(std::ios::showbase);
??????????????? getOutput().setf((std::ios::fmtflags)nAdjust, std::ios::adjustfield);
??????????????? if (nWidth != -1)
??????????????????????? nWidth = getOutput().width(nWidth);
??????????????? chFill = getOutput().fill(chFill);

??????????????? getOutput() << static_cast(nVal);

??????????????? getOutput().flags(nFlags);
??????????????? if (nWidth != -1)
??????????????????????? getOutput().width(nWidth);
??????????????? getOutput().fill(chFill);

??????????????? return outputPrefix();
??????? }
??????? 還可以增加浮點數、字符串等等的格式處理。
???????????????
??? 5、現在輸入的格式字符串,在類里面只是使用const char * m_lpszFormat來保存,一旦傳入的
lpszFormat所指的資源已經被釋放,則會造成非法內存訪問。例如:
??? std::string???? getString(void) { ..... }
??? stream.format(getString().c_str());
??? stream.arg(...);
??? 如果要避免這種情況,應該在format_stream里面增加一個std::string成員,記錄字符串指針。
又或者應該寫成:
??? std::string strTemp = getString();
??? stream.format(strTemp.c_str());
??? stream.arg(...)
應該如何處理,還是看各人的習慣和需求了。
???????
??? 6、當輸入參數比占位符多的時候,則多余的參數都會輸出到格式字符串的后面。
??? 7、當輸入參數比占位符少的時候,輸出則停留在第一個多余的占位符的前面。
??? 8、對于字符串,可以使用stringstream來輔助:
??? stringstream str;
??? format_stream fmt(str);
??? fmt.format(".....").arg(...);
??? myFun(str.str());
??? 當然,經過適當的改造,可以使類更方便使用,這里就不再多說,各位高手自己發揮了。

posted on 2005-10-08 14:25 cyt 閱讀(952) 評論(0)  編輯 收藏 引用
 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美成人亚洲成人日韩成人| 欧美超级免费视 在线| 国产日韩欧美成人| 欧美视频一区二区三区在线观看| 欧美成人国产va精品日本一级| 久久久免费av| 欧美成人免费全部| 国产精品爱啪在线线免费观看| 国产精品白丝av嫩草影院| 国产精品福利在线观看| 国产欧美一区二区三区视频| 亚洲成人直播| 欧美日韩不卡在线| 欧美日韩精品高清| 国产精品女人网站| 欧美高清在线一区| 亚洲精品美女久久7777777| 中文一区二区| 毛片基地黄久久久久久天堂| 欧美美女喷水视频| 国产乱码精品一区二区三| 国产日韩亚洲欧美精品| 亚洲国产精品久久91精品| 亚洲天堂久久| 欧美1级日本1级| 亚洲一区欧美激情| 欧美成人免费小视频| 国产精品一区一区| 亚洲国产精品一区二区久| 亚洲欧美在线另类| 欧美国产日产韩国视频| 午夜一区在线| 欧美日韩一区二区免费在线观看| 在线电影欧美日韩一区二区私密| 一区二区久久久久| 欧美成人精品一区二区| 亚洲一区二区三区精品在线 | 欧美有码视频| 最新国产成人在线观看| 久久成人18免费观看| 国产精品xvideos88| 亚洲欧洲在线播放| 久久久噜噜噜久久中文字免| 一区二区三区国产盗摄| 欧美高清视频一区| 有码中文亚洲精品| 久久久久一区| 欧美一区二区| 国产日韩专区| 欧美中文字幕在线| 亚洲一区三区视频在线观看| 欧美久久久久久久| 亚洲人成小说网站色在线| 久久亚洲高清| 欧美亚洲一区二区三区| 国产精品视频专区| 欧美在线观看日本一区| 亚洲午夜精品久久| 欧美视频免费看| 亚洲一区尤物| 亚洲一二三级电影| 国产精品视频1区| 午夜视频一区二区| 亚洲视频日本| 国产精品亚洲综合一区在线观看| 亚洲欧美日韩精品一区二区| 亚洲免费大片| 欧美亚男人的天堂| 亚洲欧美日韩精品一区二区| 亚洲男女毛片无遮挡| 国产免费亚洲高清| 欧美福利视频在线| 亚洲精品国偷自产在线99热| 亚洲毛片一区| 国产精品久久久久7777婷婷| 亚洲欧美日韩第一区| 亚洲在线视频免费观看| 99精品视频网| 久久综合久久综合久久| 亚洲国产日韩欧美综合久久| 亚洲福利小视频| 欧美日韩情趣电影| 亚洲女性裸体视频| 西西裸体人体做爰大胆久久久| 国产一区在线看| 免费观看久久久4p| 欧美日韩激情小视频| 欧美在线日韩| 蜜桃av综合| 亚洲欧美日本日韩| 久久亚洲精选| 亚洲综合好骚| 久久久久久久久岛国免费| 亚洲欧洲视频| 性久久久久久久| 亚洲国产精品国自产拍av秋霞| 亚洲黄色有码视频| 国产女主播一区二区三区| 亚洲电影欧美电影有声小说| 欧美日韩一区二区在线观看视频| 久久riav二区三区| 欧美国产精品v| 久久国产精品一区二区三区| 欧美.www| 久久精品国产久精国产一老狼| 欧美刺激午夜性久久久久久久| 午夜天堂精品久久久久| 欧美国产精品日韩| 久久久久久高潮国产精品视| 欧美连裤袜在线视频| 六月婷婷一区| 国产欧美二区| 宅男在线国产精品| 亚洲精品资源| 久久久久久久久久久一区| 性久久久久久久| 欧美日韩在线播放一区二区| 欧美国产精品| 国产在线视频欧美一区二区三区| 99精品视频免费| 亚洲免费观看在线视频| 久久av红桃一区二区小说| 亚洲欧美久久久| 欧美揉bbbbb揉bbbbb| 亚洲国产精品欧美一二99| 在线电影欧美日韩一区二区私密| 午夜精品久久久久久久99黑人| 亚洲美女av网站| 欧美国产第一页| 欧美jizz19hd性欧美| 一区二区视频在线观看| 久久成人国产| 久久精品久久综合| 国产精品最新自拍| 亚洲在线播放电影| 午夜久久影院| 国产精品成人免费| 中国女人久久久| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 欧美日韩国产成人| 亚洲午夜影视影院在线观看| 91久久夜色精品国产网站| 亚洲大胆美女视频| 米奇777在线欧美播放| 欧美国产乱视频| 亚洲精品久久久久中文字幕欢迎你 | 国产精品久久久久久户外露出| 一本综合久久| 欧美一级网站| 国产综合第一页| 噜噜噜躁狠狠躁狠狠精品视频| 欧美大片91| 夜夜精品视频| 国产美女精品| 久久久久久高潮国产精品视| 欧美mv日韩mv国产网站app| 亚洲欧洲另类| 欧美日韩小视频| 午夜视频一区在线观看| 免费看精品久久片| 99re8这里有精品热视频免费 | 一区二区在线不卡| 欧美精品123区| 亚洲淫片在线视频| 免费不卡在线观看av| 亚洲精品国产日韩| 国产精品久久久久久久7电影 | 国产精品美女久久久免费| 亚洲欧美日本视频在线观看| 久久免费少妇高潮久久精品99| 亚洲激情电影在线| 欧美丝袜一区二区| 午夜日韩视频| 99re6这里只有精品视频在线观看| 午夜日韩在线观看| 亚洲理论在线| 国产日产精品一区二区三区四区的观看方式 | 亚洲欧美精品一区| 亚洲黄色性网站| 国产日韩欧美成人| 欧美大片免费| 欧美一区成人| 日韩西西人体444www| 另类激情亚洲| 亚洲欧美区自拍先锋| 亚洲国产日本| 国产一区二区三区黄视频| 欧美激情一二区| 久久久噜噜噜久久| 欧美一级视频免费在线观看| 亚洲美女免费视频| 欧美搞黄网站| 久久亚洲美女| 欧美一区二区成人| 亚洲图片欧洲图片av| 欧美成人午夜影院| 久久久久久久久蜜桃| 亚洲综合国产精品| av成人国产| 日韩午夜精品视频|