??xml version="1.0" encoding="utf-8" standalone="yes"?>精品欧美一区二区三区久久久,伊人热热久久原色播放www,久久人爽人人爽人人片AV http://www.shnenglu.com/Error/articles/195979.htmlEnicEnicTue, 04 Dec 2012 09:28:00 GMThttp://www.shnenglu.com/Error/articles/195979.htmlhttp://www.shnenglu.com/Error/comments/195979.htmlhttp://www.shnenglu.com/Error/articles/195979.html#Feedback0http://www.shnenglu.com/Error/comments/commentRss/195979.htmlhttp://www.shnenglu.com/Error/services/trackbacks/195979.htmltemplate <typename TValue>
class el_traits
{
public:
// typename TValue;
 typedef TValue TValueType;
 typedef TValue& TReferenceType;
};

template <typename TValue, typename TTraits = el_traits<TValue> >
class TProperty
{
public:  // C++~译器不定q里是不是类型,所以需要显C指?br /> void Get(typename const TTraits::TValueType val);
 void Set(typename TTraits::TReferenceType val);
};



Enic 2012-12-04 17:28 发表评论
]]>
Q{Q? STL全排? 非递归 全排序算?/title><link>http://www.shnenglu.com/Error/articles/195448.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Wed, 21 Nov 2012 03:17:00 GMT</pubDate><guid>http://www.shnenglu.com/Error/articles/195448.html</guid><wfw:comment>http://www.shnenglu.com/Error/comments/195448.html</wfw:comment><comments>http://www.shnenglu.com/Error/articles/195448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Error/comments/commentRss/195448.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Error/services/trackbacks/195448.html</trackback:ping><description><![CDATA[     摘要:     Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//全排列算法:    //        //&n...  <a href='http://www.shnenglu.com/Error/articles/195448.html'>阅读全文</a><img src ="http://www.shnenglu.com/Error/aggbug/195448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Error/" target="_blank">Enic</a> 2012-11-21 11:17 <a href="http://www.shnenglu.com/Error/articles/195448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对C++ Local的经典分?/title><link>http://www.shnenglu.com/Error/articles/195378.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Mon, 19 Nov 2012 11:31:00 GMT</pubDate><guid>http://www.shnenglu.com/Error/articles/195378.html</guid><wfw:comment>http://www.shnenglu.com/Error/comments/195378.html</wfw:comment><comments>http://www.shnenglu.com/Error/articles/195378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Error/comments/commentRss/195378.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Error/services/trackbacks/195378.html</trackback:ping><description><![CDATA[<div><div clearfix"=""><h2>使用fstream操作文g的时候突然发C文字W无法识别了Q最后发现是local的问题!Q!<br />//////////////////////////////////////////////////////////////<br /><br />对C++ Local的经典分?/h2></div> <div class="lrvrrrb" id="content" mod-cs-content="" text-content="" clearfix"=""> <p> </p>文章地址Q?http://kittsoft.xp3.biz/?p=86<a href="http://www.shnenglu.com/deane/archive/2011/lf426/archive/2010/06/26/118788.html" target="\"_blank\""></a> <p><br /></p> <p>“q个问题比你惌中复?#8221;<br />Q我也学下BS的风|虽然q句话是我自׃时想说的。^^Q?br />从字W到整数<br />char是一U整数类型,q句话的含义是,char所能表C的字符在C/C++中都是整数类型。好Q接下来Q很多文章就会DZ个典型例子,比如Q?#8217;a' 的数值就?×61。这U说法对吗?如果你细心的读过K&R和BS对于C和C++描述的原著,你就会马上反驳道Q?×61只是’a'的ASCII |q没有Q何规定C/C++的char值必d应ASCII。C/C++甚至没有规定char占几位,只是规定了sizeof(char){于1?br />当然Q目前大部分情况下,char?位的Qƈ且,在ASCII范围内的|与ASCII对应?br />本地化策略集QlocaleQ?br />“?#8217;a'译?×61的整数?#8221;Q?#8220;ASCII范围内的~码与char的整数值对应v?#8221;Q类DL规定Q是特定pȝ和特定编译器制定 的,C/C++中有个特定的名词来描q这U规定的集合Q本地化{略集(locale。也有翻译成“现场”Q。而翻?#8212;—也就是代码{换(codecvtQ? 只是q个集合中的一个,C++中定义ؓ{略Qfacet。也有翻译ؓ“刻面”Q?br />C/C++的编译策?br />“本地化策略集”是个很好的概念,可惜在字W和字符串这个层面上QC/C++q不使用QC++的locale通常只是影响(streamQ)QC/C++使用更直接简单的{略Q硬~码?br />单的_字符Q串Q在E序文gQ可执行文gQ非源文Ӟ中的表示Q与在程序执行中在内存中的表CZ致。考虑两种情况Q?br />A、char c = 0×61;<br />B、char c = ‘a’;<br />情况A下,~译器可以直接认识作为整数的cQ但是在情况B下,~译器必d’a'译成整数。编译器的策略也很简单,是直接d字符Q串Q在源文件中的编码数倹{比如:<br />const char* s = “中文abc”;<br />q段字符串在GB2312QWindows 936Q,也就是我们的windows默认中文pȝ源文件中的编码ؓQ?br />0xD6   0xD0   0xCE 0xC4 0×61 0×62 0×63<br />在UTF-8Q也是Linux默认pȝ源文件中的编码ؓQ?br />0xE4   0xB8   0xAD   0xE6   0×96   0×87   0×61   0×62   0×63<br />一般情况下Q编译器会忠实于源文件的~码为s赋|例外的情冉|如VC会自作聪明的把大部分其他cd~码的字W串转换成GB2312Q除了像UTF-8 without signatureq样的幸存者)?br />E序在执行的时候,s也就保持是这L~码Q不会再做其他的转换?br />宽字W? wchar_t<br />正如char没有规定大小Qwchar_t同样没有标准限定Q标准只是要求一个wchar_t可以表示Mpȝ所能认识的字符Q在win32 中,wchar_t?6位;Linux中是32位。wchar_t同样没有规定~码Q因为Unicode的概忉|们后面才解释Q所以这里只是提一下,? win32中,wchar_t的编码是UCS-2BEQ而Linux中是UTF-32BEQ等价于UCS-4BEQ,不过单的_?6位以内,一个字 W的q?U编码值是一L。因此:<br />const wchar_t* ws = L”中文abc”;<br />的编码分别ؓQ?br />0x4E2D   0×6587    0×0061   0×0062   0×0063                                                //win32Q?6?br />0x00004E2D   0×00006587    0×00000061   0×00000062   0×00000063        //LinuxQ?2?br />大写的L是告诉编译器Q这是宽字符丌Ӏ所以,q时候是需要编译器Ҏlocale来进行翻译的?br />比如Q在Windows环境中,~译器的译{略是GB2312到UCS-2BEQLinux环境中的{略是UTF-8到UTF-32BE?br />q时候就要求源文件的~码与编译器的本地化{略集中代码译的策略一_例如VC只能dGB2312的源代码Q这里还是例外,VC太自作聪明了 Q会很多其他代码在~译时自动{换成GB2312Q,而gcc只能dUTF-8的源代码Q这里就有个尬QMinGWq行win32下,所以只? GB2312pȝ才认Q而MinGW却用gcc~写Q所以自己只认UTF-8Q所以结果就是,MinGW的宽字符被废掉了Q?br />宽字W(Ԍq译器译Q还是被编码进E序文g中?/p> <p>Unicode和UCS<br />Unicode和UCS是两个独立的l织分别制定的一套编码标准,但是因ؓ历史的原因,q两套标准是完全一L。Unicodeq个词用得比较多的原因可 能是因ؓ比较ҎCQ如果没有特别的声明Q在本文所提及的Unicode和UCS是一个意思。Unicode的目标是建立一套可以包含hcL有语a? 字符号你惛_到想不到的各U东西的~码Q其~码定w甚至预留了火星语以及银河pM外语a的空?#8212;—开个玩W,反正单的_Unicode~码集够的 大,如果用计机单位来表C,其数量比3个字节大一些,不到4个字节?br />Unicode和UTF<br />因ؓUnicode包含的内容太多,其编码在计算Z的表C方法就成ؓ了一个有必要研究的问题。传l编码,比如标准?位ASCIIQ在计算Z的表C方 法就是占一个字节的?位,q似乎是不需要解释就W合大家习惯的表C方法。但是当今Unicode的L辑ֈ32位(计算机的最单位是字节Q所以大? 字节Q就只能臛_?字节表示Q,对于大部分常用字W,比如Unicode~码只占一个字节大的p字母Q占两个字节大小汉字Q都?个字节来储存太奢 侈了。另外,如果都用4字节直接表示Q就不可避免的出Cؓ0的字节。而我们知道,在C语言中,0×00的字节就?#8217;\0′Q表C的是一个字W串Qchar 字符Ԍ非wchar_tQ的l束Q换句话_C风格的char字符串无法表CUnicode?br />因ؓcM的种U问题,为Unicode在计机中的~码Ҏ出现了,q就是UTFQ所对应的,为UCS~码实现的方式也有自q说法。一般来_UTF- xQx表示q套~码一个单位至占用x位,因ؓUnicode最长达?2位,所以UTF-x通常是变长的——除了UTF-32Q而UCS-y表示一个单 位就占用y个字节,所以能表示当今Unicode的UCS-y只有UCS-4Q但是因为历史的原因Q当Unicodeq没那么庞大的时候,2个字节够表 C,所以有UCS-2Q现在看来,UCS-2所能表C的Unicode只是当今Unicode的一个子集?br />也就是说Q如果某U编码,能根据一定的规则法Q得到Unicode~码Q那么这U编码方式就可以UC为UTF?br />UTF-8和Windows GB2312<br />UTF-8是一?#8220;聪明”的编码,可能?Q?Q?Q?个字节表C。通过UTF-8的算法,每一个字节表C的信息都很明确Q这是不是某个Unicode~? 码的W一个字节;如果是第一个字节,q是一个几位Unicode~码。这U?#8220;聪明”被称为UTF-8的自我同步,也是UTF-8成ؓ|络传输标准~码的原 因?br />另外QUTF-8也不会出?字节Q所以可以表CZؓchar字符Ԍ所以可以成为系l的~码。Linuxpȝ默认使用UTF-8~码?br />Windows GB2312一般自UCؓGB2312Q其实真正的名字应该是Windows Codepage 936Q这也是一U变长的~码Q?个字节表CZl的ASCII部分Q汉字部分是两个字节的GBKQ国标扩Q展Q,拼音声母Q。Codepage 936也可以表CZؓchar字符Ԍ是中文Windowspȝ的默认编码?br />我们在第1节中看到?br />const char* s = “中文abc”;<br />在Windows中的~码是Codepage 936Q在Linux中的~码是UTF-8?br />需要注意的是,Codepage 936不像UTFQ跟Unicode没有换算的关p,所以只能通过“代码?#8221;技术查表对应?br />UTF-16和UCS-2<br />UTF-16?个字节或?个字节表C。在2个字节大的时候,跟UCS-2是一L。UTF-16不像UTF-8Q没有自我同步机Ӟ所以,~码大位 在前q是位在前Q就成了见仁见智的问题。我们在W?节中Q?#8220;?#8221;的UCS-2BEQ因为是两个字节Q所以也是UTF-16BEQ编码是0x4E2DQ? q里的BE是大位在后的意思(也就是小位在前了Q,对应的,如果是UCS-2LEQ编码就成了0x2D4E?br />Windows中的wchar_t是采用UCS-2BE~码。需要指出的是,C++标准中对wchar_t的要求是要能表示所有系l能识别的字W。Windows自称支持UnicodeQ但是其wchar_t却不能表C所有的UnicodeQ由此违背了C++标准?br />UTF-32和UCS-4<br />UTF-32在目前阶D늭价于UCS-4Q都用定长的4个字节表C。UTF-32同样存在BE和LE的问题。Linux的wchar_t~码是UTF- 32BE。在16位以内的时候,UTF-32BE的后两位Q前两位?×00 0×00Q等价于UTF-16BE也就{h于UCS-2BE<br />BOM<br />Z说明一个文仉用的是什么编码,在文件最开始的部分Q可以有BOMQ比?xFE 0xFF表示UTF-16BEQ?xFF 0xFE 0×00 0×00表示UTF-32LE。UTF-8原本是不需要BOM的,因ؓ其自我同步的Ҏ,但是Z明确说明q是UTF-8Q而不是让文本~辑器去猜)Q也 可以加上UTF-8的BOMQ?xEF 0xBB 0xBF<br />以上内容都讲q得很概略,详细信息h阅维基百U相兛_宏V?/p> <p>std::locale<br />通过前面两节的知识,我们知道了在C/C++中,字符Q串Q和宽字W(Ԍ之间的{换不是简单的Q固定的数学关系Q宽H{换依赖于本地化策略集 QlocaleQ。换句话_一个程序在q行之前q不知道pȝ的本地化{略集是什么,E序只有在运行之后才通过locale获得当时的本地化{略集?br />C有自qlocale函数Q我们这里直接介lC++的localecR?br />先讨论locale的构造函敎ͼ<br />locale() throw();<br />q个构造函数是获得当前E序的localeQ用法如下:<br />std::locale app_loc = std::locale();<br />或者(q是构造对象的两种表示方式Q后同)<br />std::locale app_loc;<br />另外一个构造函数是Q?br />explicit locale(const char* name);<br />q个构造函Cname的名字创建新的locale。重要的locale对象有:<br />std::locale sys_loc(“”);      //获得当前pȝ环境的locale<br />std::locale C_loc(“C”);      或?nbsp;     std::locale C_loc = std::locale::classic();      //获得C定义locale<br />std::locale old_loc = std::locale::global(new_loc);      //new_loc讄为当前全局localeQƈ原来的localeq回lold_loc<br />除了q些Q其它的name具体名字依赖于C++~译器和操作pȝQ比如Linux下gcc中文pȝ的locale名字?#8221;zh_CN.UTF-8″Q中文Windows可以?#8221;chs”Q更加完整的名字可以用name()函数查看Q?br />mbstowcs()和wcstombs()<br />q两个Cq行时库函数依赖于全局localeq行转换Q所以,使用前必d讄全局locale?br />std::locale已经包含?lt;iostream>中了Q再加上我们需要用到的C++字符Ԍ所以包?lt;string>?br />我们先看H到宽的转换函数Q?/p> <ol> <li>const std::wstring s2ws(const std::string& s)    </li><li>{    </li><li>    std::locale old_loc = std::locale::global(std::locale(""));    </li><li>    const char* src_str = s.c_str();    </li><li>    const size_t buffer_size = s.size() + 1;    </li><li>    wchar_t* dst_wstr = new wchar_t[buffer_size];    </li><li>    wmemset(dst_wstr, 0, buffer_size);    </li><li>    mbstowcs(dst_wstr, src_str, buffer_size);    </li><li>    std::wstring result = dst_wstr;    </li><li>    delete []dst_wstr;    </li><li>    std::locale::global(old_loc);    </li><li>    return result;    </li><li>}   </li><li>  </li></ol> <p>我们全局locale讄为系llocaleQƈ保存原来的全局locale在old_loc中?br />在制定{换空间缓存大的时候,考虑如下Qchar是用1个或多个对象Q也是1个或者多个字节来表示各种W号Q比如,GB2312?个字节表C数字和 字母Q?个字节表C汉字;UTF-8用一个字节表C数字和字母Q?个字节表C汉字,4个字节表CZ些很用到的W号Q比如音乐中G大调W号{? wchar_t是用1个对象(2字节或?字节Q来表示各种W号。因此,表示同样的字W串Q宽字符串的大小Q也是wchar_t对象的数量)L于? 者等于窄字符串大(char对象数量Q的?1是ؓ了在最后预留一个gؓ0的对象,以便让C风格的char或者wchar_t字符串自动截?#8212;—q当? 是宽串大等于窄串大的时候才会用上的Q大部分时候,字符串早在前面某个{换完毕的位置p0值对象所截断了?br />最后我们将全局locale讄回原来的old_loc?br />H串到宽串的转换函数Q?/p> <ol> <li>const std::string ws2s(const std::wstring& ws)    </li><li>{    </li><li>    std::locale old_loc = std::locale::global(std::locale(""));    </li><li>    const wchar_t* src_wstr = ws.c_str();    </li><li>    size_t buffer_size = ws.size() * 4 + 1;    </li><li>    char* dst_str = new char[buffer_size];    </li><li>    memset(dst_str, 0, buffer_size);    </li><li>    wcstombs(dst_str ,src_wstr, buffer_size);    </li><li>    std::string result = dst_str;    </li><li>    delete []dst_str;    </li><li>    std::locale::global(old_loc);    </li><li>    return result;    </li><li>}   </li><li>  </li></ol> <p>q里考虑转换I间~存大小的策略正好相反,在最极端的情况下Q所有的wchar_t都需?个char来表C,所以最大的可能是4倍加1?br />q两个函数在VC和gcc中都能正常运行(MinGW因ؓ前面说到的原因不支持宽字W的正常使用Q,在VC中会l出不安全的警告Q这是告诉给那些弄不清宽H{换实质的人的警告Q对于了解到目前q些知识的你我来_q就是啰嗦了?/p> <p>locale和facet<br />C++的locale框架比C更完备。C++除了一个笼l本地策略集localeQ还可以为locale指定具体的策略facetQ甚臛_以用自己定义? facetL造一个现有的locale产生一个新的locale。如果有一个facetcNewFacet需要添加到某个old_loc中Ş成新 new_locQ需要另外一个构造函敎ͼ通常的做法是Q?br />std::locale new_loc(old_loc, new NewFacet);<br />标准库里的标准facet都具有自q有的功能Q访问一个locale对象中特定的facet需要用模板函数use_facetQ?br />template <class Facet> const Facet& use_factet(const locale&);<br />换一U说法,use_facet把一个facetcd例化成了对象Q由此就可以使用q个facet对象的成员函数?br />codecvt<br />codecvt是一个标准facet。在C++的设计框枉Q这是一个通用的代码{换模?#8212;—也就是说Qƈ不是仅仅为宽H{换制定的?br />templat <class I, class E, class State> class std::codecvt: public locale, public codecvt_base{…};<br />I表示内部~码QE表示外部~码QState是不同{换方式的标识Q如果定义如下类型:<br />typedef std::codecvt<wchar_t, char, mbstate_t> CodecvtFacet;<br />那么CodecvtFacet是一个标准的宽窄转换facetQ其中mbstate_t是标准宽H{换的State?br />内部~码和外部编?br />我们考虑W?节中提到的C++~译器读取源文g时候的情ŞQ当dL”中文abc”的时候,外部~码Q也是源文件的~码Q是GB2312或者UTF-8 的charQ而编译器必须其译为UCS-2BE或者UTF-32BE的wchar_tQ这也就是程序的内部~码。如果不是宽字符Ԍ内外~码都是 charQ也׃需要{换了。类似的Q当C++d文g的时? Q就会可能需要到内外~码转换。事实上Qcodecvt正是被文g缓存basic_filebuf所使用的。理解这一点很重要Q原因会在下一节? 到?br />CodecvtFacet的in()和out()<br />因ؓ在CodecvtFacet中,内部~码讄为wchar_tQ外部编码设|ؓcharQ{换模式是标准宽窄转换mbstate_tQ所以,cL? in()是从char标准转换到wchar_tQout()是从wchar_t标准转换到char。这成了我们正需要的内外转换函数?br />result in(State& s, const E* from, const E* from_end, const E*& from_next, I* to,  I* to_end, I*& to_next) const;<br />result out(State& s, const I* from, const I* from_end, const I*& from_next, E* to, E* to_end, E*& to_next) const;<br />其中Qs是非const引用Q保存着转换位移状态信息。这里需要重点强调的是,因ؓ转换的实际工作交l了q行时库Q也是_转换可能不是在程序的主进E? 中完成的Q而{换工作依赖于查询s的|因此Q如果s在{换结束前析构Q就可能抛出q行时异常。所以,最安全的办法是Q将s讄为全局变量Q?br />const?个指针分别是待{换字W串的v点,l点Q和出现错误时候的停点Q的下一个位|)Q另?个指针是转换目标字符串的LQ终点以及出现错误时候的停点Q的下一个位|)?br />代码如下Q?br />头文Ӟ</p> <ol> <li>//Filename string_wstring_cppcvt.hpp    </li><li>#ifndef STRING_WSTRING_CPPCVT_HPP    </li><li>#define STRING_WSTRING_CPPCVT_HPP    </li><li>#include <iostream>    </li><li>#include <string>    </li><li>const std::wstring s2ws(const std::string& s);    </li><li>const std::string ws2s(const std::wstring& s);    </li><li>#endif   </li><li>  </li></ol> <p>实现Q?/p> <ol> <li>#include "string_wstring_cppcvt.hpp"    </li><li>mbstate_t in_cvt_state;    </li><li>mbstate_t out_cvt_state;    </li><li>const std::wstring s2ws(const std::string& s)    </li><li>{    </li><li>    std::locale sys_loc("");    </li><li>    const char* src_str = s.c_str();    </li><li>    const size_t BUFFER_SIZE = s.size() + 1;    </li><li>    wchar_t* intern_buffer = new wchar_t[BUFFER_SIZE];    </li><li>    wmemset(intern_buffer, 0, BUFFER_SIZE);    </li><li>    const char* extern_from = src_str;    </li><li>    const char* extern_from_end = extern_from + s.size();    </li><li>    const char* extern_from_next = 0;    </li><li>    wchar_t* intern_to = intern_buffer;    </li><li>    wchar_t* intern_to_end = intern_to + BUFFER_SIZE;    </li><li>    wchar_t* intern_to_next = 0;    </li><li>    typedef std::codecvt<wchar_t, char, mbstate_t> CodecvtFacet;    </li><li>    CodecvtFacet::result cvt_rst =    </li><li>    std::use_facet<CodecvtFacet>(sys_loc).in(    </li><li>            in_cvt_state,    </li><li>            extern_from, extern_from_end, extern_from_next,    </li><li>            intern_to, intern_to_end, intern_to_next);    </li><li>    if (cvt_rst != CodecvtFacet::ok) {    </li><li>        switch(cvt_rst) {    </li><li>        case CodecvtFacet::partial:    </li><li>                std::cerr << "partial";    </li><li>                break;    </li><li>        case CodecvtFacet::error:    </li><li>                std::cerr << "error";    </li><li>                break;    </li><li>        case CodecvtFacet::noconv:    </li><li>                std::cerr << "noconv";    </li><li>                break;    </li><li>        default:    </li><li>                std::cerr << "unknown";    </li><li>        }    </li><li>        std::cerr  << ", please check in_cvt_state."    </li><li><< std::endl;    </li><li>    }    </li><li>    std::wstring result = intern_buffer;    </li><li>    delete []intern_buffer;    </li><li>    return result;    </li><li>}    </li><li>const std::string ws2s(const std::wstring& ws)    </li><li>{    </li><li>    std::locale sys_loc("");    </li><li>    const wchar_t* src_wstr = ws.c_str();    </li><li>    const size_t MAX_UNICODE_BYTES = 4;    </li><li>    const size_t BUFFER_SIZE =    </li><li>                ws.size() * MAX_UNICODE_BYTES + 1;    </li><li>    char* extern_buffer = new char[BUFFER_SIZE];    </li><li>    memset(extern_buffer, 0, BUFFER_SIZE);    </li><li>    const wchar_t* intern_from = src_wstr;    </li><li>    const wchar_t* intern_from_end = intern_from + ws.size();    </li><li>    const wchar_t* intern_from_next = 0;    </li><li>    char* extern_to = extern_buffer;    </li><li>    char* extern_to_end = extern_to + BUFFER_SIZE;    </li><li>    char* extern_to_next = 0;    </li><li>    typedef std::codecvt&lt;wchar_t, char, mbstate_t> CodecvtFacet;    </li><li>    CodecvtFacet::result cvt_rst =    </li><li>    std::use_facet<CodecvtFacet>(sys_loc).out(    </li><li>            out_cvt_state,    </li><li>            intern_from, intern_from_end, intern_from_next,    </li><li>            extern_to, extern_to_end, extern_to_next);    </li><li>    if (cvt_rst != CodecvtFacet::ok) {    </li><li>        switch(cvt_rst) {    </li><li>        case CodecvtFacet::partial:    </li><li>                std::cerr << "partial";    </li><li>                break;    </li><li>        case CodecvtFacet::error:    </li><li>                std::cerr << "error";    </li><li>                break;    </li><li>        case CodecvtFacet::noconv:    </li><li>                std::cerr << "noconv";    </li><li>                break;    </li><li>        default:    </li><li>                std::cerr << "unknown";    </li><li>        }    </li><li>        std::cerr << ", please check out_cvt_state."    </li><li><< std::endl;    </li><li>    }    </li><li>    std::string result = extern_buffer;    </li><li>    delete []extern_buffer;    </li><li>    return result;    </li><li>}   </li><li>  </li></ol> <p>最后补充说明一下std::use_facet&lt;CodecvtFacet>(sys_loc).in()? std::use_facet<CodecvtFacet>(sys_loc).out()。sys_loc是系l的localeQ这? locale中就包含着特定的codecvt facetQ我们已ltypedefZCodecvtFacet。用use_facet对CodecvtFacetq行了实例化Q所以可以用这? facet的方法in()和out()?/p> <p>C++的流和本地化{略?br />BS在设计C++的时候希望其具备化,q且是可扩展的智能化Q也是_C++的流可以“L”一些内宏V比如:</p> <p>std::cout <&lt; 123 &lt;&lt; “ok” &lt;&lt; std::endl;</p> <p>q句代码中,std::cout是能判断?23是int?#8221;ok”是const char[3]。利用流的智能,甚至可以做一些基cd的{换,比如从int到stringQstring到intQ?/p> <ol> <li>std::string str("123");    </li><li>std::stringstream sstr(str);    </li><li>int i;    </li><li>sstr >&gt; i;   </li><li>  </li><li>int i = 123;    </li><li>std::stringstream sstr;    </li><li>sstr <&lt; i;    </li><li>std::string str = sstr.str();   </li><li>  </li></ol> <p>管如此QC++q不满QC++甚至希望能“明白”旉Q货币的表示法。而时间和货币的表C方法在世界范围内是不同的,所以,每一个流都有自己 的locale在媄响其行ؓQC++中叫做激z(imbueQ也有翻译成染Q。而我们知道,每一个locale都有多个facetQ这些facetq L被use_facet使用的。决定用哪些facet的,是流的缓存basic_streambuf及其zcbasic_stringbuf? basic_filebuf。我们要用到的facet是codecvtQ这个facet只被basic_filebuf使用——q就是ؓ什么只能用 fstream来实现宽H{换,而无法用sstream来实现的原因?br />头文Ӟ</p> <ol> <li>//filename string_wstring_fstream.hpp    </li><li>#ifndef STRING_WSTRING_FSTREAM_HPP    </li><li>#define STRING_WSTRING_FSTREAM_HPP    </li><li>#include &lt;string>    </li><li>const std::wstring s2ws(const std::string& s);    </li><li>const std::string ws2s(const std::wstring& s);    </li><li>#endif  </li></ol> <p>实现Q?/p> <ol> <li>#include <string>    </li><li>#include <fstream>    </li><li>#include "string_wstring_fstream.hpp"    </li><li>const std::wstring s2ws(const std::string& s)    </li><li>{    </li><li>    std::locale sys_loc("");    </li><li>    std::ofstream ofs("cvt_buf");    </li><li>    ofs <&lt; s;    </li><li>    ofs.close();    </li><li>    std::wifstream wifs("cvt_buf");    </li><li>    wifs.imbue(sys_loc);    </li><li>    std::wstring wstr;    </li><li>    wifs >&gt; wstr;    </li><li>    wifs.close();    </li><li>    return wstr;    </li><li>}    </li><li>const std::string ws2s(const std::wstring& s)    </li><li>{    </li><li>    std::locale sys_loc("");    </li><li>    std::wofstream wofs("cvt_buf");    </li><li>    wofs.imbue(sys_loc);    </li><li>    wofs <&lt; s;    </li><li>    wofs.close();    </li><li>    std::ifstream ifs("cvt_buf");    </li><li>    std::string str;    </li><li>    ifs >&gt; str;    </li><li>    ifs.close();    </li><li>    return str;    </li><li>}   </li><li>  </li></ol> <p>在窄到宽的{化中Q我们先使用默认的本地化{略集(localeQ将s通过H文件流ofs传入文gQ这是char到char的传递,没有M转换Q? 然后我们打开宽文件流wifsQƈ用系l的本地化策略集QlocaleQ去Ȁz(imbueQ之Q流在读回宽串wstr的时候,是char? wchar_t的{换,q且因ؓȀzMsys_locQ所以实现标准窄到宽的{换?br />在宽到窄的{化中Q我们先打开的是宽文件流wofsQƈ且用pȝ的本地化{略集sys_locȀz(imbueQ之Q这时候,因ؓ要写的文? cvt_buf是一个外部编码,所以执行了从wchar_t到char的标准{换。读回来的文件流从char到charQ不做Q何{换?/p> <p>编码的伤<br />我们现在知道QC/C++的宽H{换是依赖pȝ的locale的,q且在运行时完成。考虑q样一U情况,我们在简体中文Windows下编译如下语句:<br />const char* s = “中文abc”;<br />Ҏ我们之前的讨论,~译器将按照Windows Codepage936QGB2312Q对q个字符串进行编码。如果我们在E序中运行宽H{换函敎ͼs转换为宽字符串wsQ如果这个程序运行在体中? 环境下是没问题的Q将执行从GB2312到UCS-2BE的{换;但是Q如果在其他语言环境下,比如是繁体中文BIG5Q程序将Ҏpȝ的locale? 行从BIG5到UCS-2BE的{换,q显然就出现了错误?br />补救<br />有没有补救这个问题的办法呢?一个解x案就是执行不依赖locale的宽H{换。实际上Q这已l不是宽H{换之间的问题了,而是~码之间转换的问? 了。我们可以用GNU的libiconv实现L~码间的转换Q对于以上的具体情况Q指明是从GB2312到UCS-2BE׃会出错。(请参考本人前?的章节:<a href="http://www.shnenglu.com/deane/archive/2011/lf426/archive/2008/03/30/45738.html" target="\"_blank\"">win32下的libiconv</a>Q,但这昄是一个笨拙的{略Q我们在体中文Windows下必M用GB2312到UCS-2BE版本的宽H{换函敎ͼCBIG5环境下,必重新写从BIG5到UCS-2BE的宽H{换函数?br />Windows的策?br />Windows的策略是淘汰了窄字符Ԍq脆只用宽字W串。所有的编码全部加上特定宏Q比如TEXT()Q如果程序是所谓Unicode~译Q在~译时就译为UCS2-BE——Windows自称为Unicode~程Q其本质是用了UCS-2BE?6位宽字符丌Ӏ?br />Linux的策?br />Linux下根本就不存在这个问题!因ؓ各种语言的Linux都用UTF-8的编码,所以,无论pȝlocale如何变化Q窄到宽转换的规则一直是UTF-8到UTF32-BE ?br />跨^台策?br />因ؓ?6位的范围内,UTF32-BE的前16位ؓ0Q后16位与UCS2-BE是一LQ所以,即wchar_t的sizeof()不一P在一般情况下Q跨q_使用宽字W(Ԍ也应该是兼容的。但是依然存在潜在的问题Q就是那?字节的UTF32~码?br />gettext{略<br />以上都是ASCII及以外的~码编码在E序中的办法。GNU的gettext提供了另外一U选择Q在E序中只编码ASCIIQ多语言支持由gettext函数库在q行时加载。(对gettext的介l请参考本人前面的章节Q?a href="http://www.shnenglu.com/deane/archive/2011/lf426/archive/2008/03/30/45723.html" target="\"_blank\"">Win32下的GetText</a>Q? gettext的多语言译文g不在E序中,而是单独的提出来攑֜特定的位|。gettext明确的知道这些翻译文件的~码Q所以可以准的告诉l系l翻 译的正确信息Q而系l将q些信息以当前的pȝlocale~码成窄字符串反馈给E序。例如,在简体中文Windows中,gettext的po文g也可? 以UTF-8储存Qgettextpo文g译成mo文gQ确保mo文g在Q何系l和语言环境下都能够正确译。在q行是传lwin32E序的窄串符? 当前localeQ是GB2312。gettext让国际化的翻译更加的方便Q缺Ҏ目前我没扑ֈ支持宽字W串的版本(据说是有ugettext()支持 宽字W串Q,所以要使用gettext只能使用H字W串。但是gettext可以转换到宽字符Ԍ而且不会出现宽窄转换的问题,因ؓgettext是运? 时根据locale译的。例如:<br />const char* s = gettext(“Chinese a b c”);<br />其中”Chinese a b c”在po中的译?#8221;中文abc”<br />使用依赖locale的运行时宽窄转换函数Q?br />const std::wstring wstr = s2ws(s);<br />q行时调用该po文g对应的mo文gQ在体中文环境下׃GB2312传给E序Q在J体中文中就以BIG5传给E序Q这样s2ws()总能够正常换编码?br />更多<br />在本文的最后,我想回到C++的stream问题上。用fstream转换如此的简单,sstream却不支持。改造一个支持codecvt? string stream需要改造basic_stringbuf。basic_stringbuf和basic_filebuf都派生自 basic_streambufQ所不同的是basic_filebuf在构造和open()的时候调用了codecvtQ只需要在 basic_stringbuf中添加这个功能就可以了。说hҎQ实际上是需要重新改造一个STL模板Q尽这些模板源代码都是在标准库头文件中现成 的,但是我还是水qx限,没有LI了。另外一个思\是构Z个基于内存映的虚拟文gQ这个框架在boost的iostreams库中Q有兴趣的朋友可 以深入的研究?br />Q完Q?/p>Related Posts: </div></div><img src ="http://www.shnenglu.com/Error/aggbug/195378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Error/" target="_blank">Enic</a> 2012-11-19 19:31 <a href="http://www.shnenglu.com/Error/articles/195378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fstream和vector的化学反? std::istreambuf_iterator boost::interprocess::bufferstreamhttp://www.shnenglu.com/Error/articles/194829.htmlEnicEnicWed, 07 Nov 2012 03:04:00 GMThttp://www.shnenglu.com/Error/articles/194829.htmlhttp://www.shnenglu.com/Error/comments/194829.htmlhttp://www.shnenglu.com/Error/articles/194829.html#Feedback0http://www.shnenglu.com/Error/comments/commentRss/194829.htmlhttp://www.shnenglu.com/Error/services/trackbacks/194829.html
      std::ifstream ifs("d:\\test.jpg", std::ios::in | std::ios::binary);
      std::vector<char> data((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());

注意Q这里用的是stream buffer的P代器Q而不是streamq代器。因里的以binary把数据保存到bufferQ若用streamQ则以文本格式?br />
2. 把buffer存入stream
stl提供的stream有fstreampd和stringstreampd。stringstream也可以存放binary格式。这里用boost提供的bufferstreamQ让代码看v来更介?br />
      boost::interprocess::bufferstream input_stream(&data[0], data.size());
      output(input_stream, "test.jpg");


Enic 2012-11-07 11:04 发表评论
]]>
std::fstream 句柄泄漏陷阱http://www.shnenglu.com/Error/articles/167309.htmlEnicEnicWed, 07 Mar 2012 05:01:00 GMThttp://www.shnenglu.com/Error/articles/167309.htmlhttp://www.shnenglu.com/Error/comments/167309.htmlhttp://www.shnenglu.com/Error/articles/167309.html#Feedback0http://www.shnenglu.com/Error/comments/commentRss/167309.htmlhttp://www.shnenglu.com/Error/services/trackbacks/167309.html
Qsearch key: std::fstream句柄泄漏  std::fstream析构是否关闭句柄 )

蔡亮<errorcpp@qq.com> 12:49:19 
std::fstream 析构的时候会关闭文g句柄么?
蔡亮<errorcpp@qq.com> 12:50:34 
  求stl高手指导Q,Q?br />
我记得是会关闭的Q,Q?br />矛_(172106137) 12:51:35 
ifstream?
矛_(172106137) 12:51:44 
ifstream ?br />蔡亮<errorcpp@qq.com> 12:52:35 
哦,q我放心了
矛_(172106137) 12:54:58 
嗯,
矛_(172106137) 12:55:02 
但要注意一点,
矛_(172106137) 12:55:15 
ifstream只关闭你最后一ơ打开的文件?br />蔡亮<errorcpp@qq.com> 12:56:36 
也就是说复用 fstream的时候有可能应ؓ忘记关闭句柄D泄漏Q?br />矛_(172106137) 12:56:57 
?br />蔡亮<errorcpp@qq.com> 12:57:04 
?br />矛_(172106137) 12:57:19 
它只在析构时关闭Q?br />蔡亮<errorcpp@qq.com> 12:57:41 
 
妹的Q以前没注意Q,Q?br />矛_(172106137) 12:57:40 
如果你用同一个对象操作一个文件后Q不调用closeQ却再打开另一个文Ӟ
矛_(172106137) 12:57:51 
那个handle׃没h关闭的?br />蔡亮<errorcpp@qq.com> 12:58:39 
刚刚用Q务管理器看了下,析构的时候确实关闭了Q,Q?br />
调试的时候跟q去看的太痛苦了Qn多层Q,Q?br />


********************************************************************
在后来的开发过E中我们发现一个问题:
(search key: fopen 最多打开多少句柄  fopen打开文gp|  fopen打开句柄限制)

目中出现fopen打开文gp|现象Q第一反应是文件句柄泄漏,然后查看d理器,q程句柄?400个,以往常的l验?400即是泄漏也不会严重到无法打开新的句柄。于是写代码试验证是不是fopen的问?br />
使用标准库的 fopen 打开的文件句柄L是受限制的,l过试我们发现默认情况下windowsq_使用CreateFile臛_可以创徏3w个以上的文g句柄Q而用标准库的fopen最多则只能创徏512个,后来发现标准库对q个实是有限制的,有一个函数可以设|fopen能打开的句柄个?br />
    // c标准库对fopen的文件个数有限制默认?12
    ::_setmaxstdio(2048);
linuxq_也有相应的限?br />********************************************************************
后来在网l上查到的,没有l过实际试Q仅作参考:
(search key: fstream最多打开多少句柄 )
我做q实验,fopen有限Ӟ只能同时打开46Q还?7个左?br />ofstream
fstream
CreatFileq三U方法没有限Ӟ可以同时打开很多文gQ我试的是打开10w个,再多Q我没实验了Q?/div>*********************************************************************


Enic 2012-03-07 13:01 发表评论
]]> ձѾþþþþþվ | պʮ˽һþ| 91޹˾þþƷַ| 99þþƷһ| ߾þþƷĹ | Ʒ99þþþ| պAVëƬƷþþ| ŷսþþþþþþ| 97þþƷˬ| þݺҹҹ2014| þþƷ91þ鶹| þ¶Ʒ| þۺϳDž| þòӰ| ͵͵þþþվ| AŮAVۺϾþþ| ξþ99ƷþþþþС˵| ƷȾþþø| þùȾƷҰAV| þþžѸƵ| þɫۺһ| ƷѸþ| ޹Ʒþþ | ҹþþþþýӰ| ޹˾Ʒ91þþ| Ʒþ| һƷþ| պƷþĻ| þ¶Ʒ| 뾫ƷþɪӰ| 2021˾Ʒþ| ۲ӰԺþ99| þҹɫƷ| һþaþþƷۺҹҹ| ŷƷþþ| re99þ6Ʒ| þþƷҹһ| þþþ޾Ʒ| Avþ| Ʒ18þþþþvr| þþƷ|