﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-我希望你是我独家记忆-随笔分类-资料整理</title><link>http://www.cppblog.com/Hero/category/7805.html</link><description> 一段永远封存的记忆，随风而去</description><language>zh-cn</language><lastBuildDate>Wed, 25 Nov 2009 18:39:48 GMT</lastBuildDate><pubDate>Wed, 25 Nov 2009 18:39:48 GMT</pubDate><ttl>60</ttl><item><title>程序员常用字体(vs2008字体修改方案)</title><link>http://www.cppblog.com/Hero/archive/2009/11/25/101900.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Wed, 25 Nov 2009 04:01:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/11/25/101900.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/101900.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/11/25/101900.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/101900.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/101900.html</trackback:ping><description><![CDATA[<p>字体不仅是设计师手中重要的武器，对我们开发人员来说，字体的选择也有许多讲究，一个好的、适合展示代码的字体，应该具备以下要素：</p>
<ul>
    <li>等宽的字符
    <li>简洁、清晰并且规范的字符形状
    <li>支持ASCII码为128以上的扩展字符集
    <li>与字符同等宽度的空格
    <li>易于分辨的小写字母l、大写字母I、数字1和符号|
    <li>易于分辨的大写字母O和数字0
    <li>易于分辨的前引号和后引号，最好能够前后对称
    <li>易于分辨的其他标点符号，尤其是大括号、中括号、小括号和尖括号
    <li>良好的中文支持和显示 </li>
</ul>
<p>下图展示了一个极端的反例，虽然很有个性，但并不适合用来显示代码。它的大写字母大的可怕，小写字母却小的可怜；字符不仅不清晰，而且不规范；小写字母l、大写字母I、数字1和符号| 难以分辨；大写字母O和数字0难以分辨；标点符号还凑合，只是下划线为什么是断开的？</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_33.png" width=500 height=465> </p>
<p>当然，这个反例的确有些夸张，但其上文所列举的条件是比较苛刻的，我们在选择字体时没有必要非要完全满足所有条件，事实上这种字体也是凤毛麟角。下文所分享的一些字体也并没有完全满足所有条件，我们发现，只要满足了其中一些关键条件，用来显示代码就已经很不错了。</p>
<p>在Visual Studio中，更改编辑器的字体是件简单的事情，选择菜单【<strong>工具</strong>】【<strong>选项</strong>】，在弹出的&#8220;<strong>选项</strong>&#8221;对话框中依次选择&#8220;<strong>环境</strong>&#8221;和&#8220;<strong>字体和颜色</strong>&#8221;，然后在&#8220;<strong>显示其设置</strong>&#8221;中选择&#8220;<strong>文本编辑器</strong>&#8221;，最后在&#8220;<strong>字体</strong>&#8221;中选择字体就可以了，如下图所示：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_3.png" width=625 height=311></p>
<p>在上图中，我们发现Visual Studio已经将等宽字体用粗体标识了出来，这样做是为了让我们更容易找到等宽的字体，并不表示等宽字体就一定适合显示代码，比如下图所示的&#8220;新宋体&#8221;就是一个反例：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_2.png" width=436 height=333> </p>
<p>在新宋体中，数字0之比大写字母O瘦那么一点点，小写字母l和数字1也十分相像，幸亏配色方案能够颜色将它们区别开来，否则实在难以分辨。这也从另一个角度说明了配色方案与字体是相辅相成的，搭配恰当时，会让代码更加清晰易辨。</p>
<p>下面就和大家分享一些在编程界声名烜赫的字体，截图所采用的配色方案为<a href="http://coding.windstyle.cn/2009/11/19/make-your-code-more-comfortable-1-choose-the-right-color-scheme/"><u><font color=#810081>HumaneStudio</font></u></a>，展示顺序为字体首字母升序。这些字体可能乍一看都一样，但仔细品味，还是能够发现不同的味道，希望大家都能找到适合自己的字体。</p>
<p><a href="http://sourceforge.net/projects/corefonts/files/" target=_blank><u><font color=#0000ff>Andale Mono</font></u></a>，演示字号为14，<a href="http://files.cnblogs.com/xiaoshatian/Andale-Mono.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_32.png" width=491 height=353> </p>
<p>&nbsp;</p>
<p><a href="http://www.ms-studio.com/FontSales/anonymouspro.html" target=_blank><u><font color=#0000ff>Anonymous Pro</font></u></a>，演示字号为14，<a href="http://files.cnblogs.com/xiaoshatian/AnonymousPro.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_31.png" width=485 height=367> </p>
<p>&nbsp;</p>
<p><a href="http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/" target=_blank><u><font color=#0000ff>Bitstream Vera Sans Mono</font></u></a>，演示字号为14，<a href="http://files.cnblogs.com/xiaoshatian/Bitstream-Vera-Sans-Mono.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_29.png" width=486 height=368> </p>
<p>&nbsp;</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3" target=_blank><u><font color=#0000ff>Consolas</font></u></a>，演示字号为14，Windows或Visual Studio已内置：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_28.png" width=445 height=369> </p>
<p>&nbsp;</p>
<p><a href="http://en.wikipedia.org/wiki/Courier_%28typeface%29" target=_blank><u><font color=#0000ff>Courier New</font></u></a>，演示字号为14，Windows已内置：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_27.png" width=481 height=354> </p>
<p>&nbsp;</p>
<p><a href="http://dejavu-fonts.org/wiki/index.php?title=Main_Page" target=_blank><u><font color=#0000ff>DejaVu Sans Mono</font></u></a>，演示字号为14，<a href="http://files.cnblogs.com/xiaoshatian/DejaVu-Sans-Mono.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_26.png" width=489 height=371> </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://damieng.com/fonts/envy-code-r" target=_blank><u><font color=#0000ff>Envy Code R</font></u></a>，演示字号为16，<a href="http://files.cnblogs.com/xiaoshatian/Envy-Code-R-PR7.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_24.png" width=483 height=416> </p>
<p>&nbsp;</p>
<p><a href="http://www.levien.com/type/myfonts/inconsolata.html" target=_blank><u><font color=#0000ff>Inconsolata</font></u></a>，演示字号为16，<a href="http://files.cnblogs.com/xiaoshatian/Inconsolata.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_15.png" width=472 height=353> </p>
<p>&nbsp;</p>
<p><a href="http://en.wikipedia.org/wiki/Monaco_%28typeface%29" target=_blank><u><font color=#0000ff>Monaco</font></u></a>，演示字号为12，<a href="http://files.cnblogs.com/xiaoshatian/MONACO.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_16.png" width=441 height=386> </p>
<p>&nbsp;</p>
<p><a href="http://en.wikipedia.org/wiki/Monofur" target=_blank><u><font color=#0000ff>Monofur</font></u></a>，演示字号为16，<a href="http://files.cnblogs.com/xiaoshatian/Monofur.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_17.png" width=477 height=353> </p>
<p>&nbsp;</p>
<p><a href="http://www.fsd.it/fonts/pragma.htm" target=_blank><u><font color=#0000ff>Progmata</font></u></a>，演示字号为14，<a href="http://files.cnblogs.com/xiaoshatian/Pragmata.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_22.png" width=461 height=417> </p>
<p>&nbsp;</p>
<p><a href="http://typo3.kernest.com/fonts/share-techmono" target=_blank><u><font color=#0000ff>Share TechMono</font></u></a>，演示字号为16，<a href="http://files.cnblogs.com/xiaoshatian/Share-TechMono.zip"><u><font color=#0000ff>猛击这里下载</font></u></a>：</p>
<p>注：此字体似乎会将连在一起的fl显示为一个点，不建议使用，可惜可惜。</p>
<p><img style="DISPLAY: inline" title=image alt=image src="http://images.cnblogs.com/cnblogs_com/xiaoshatian/WindowsLiveWriter/2_AEFE/image_thumb_19.png" width=478 height=401> </p>
<p>尾注：</p>
<ul>
    <li>本文所分享的字体均支持ClearType。
    <li>从评论来看，中文的显示的确是一个影响美观的重要因素，所以产生了许多微软雅黑和一些优秀英文字体的混合版，但其实还有一种方法可以快速而简单的实现用不同的字体显示中英文（感谢<a id=Comments1_CommentList_ctl52_NameLink href="http://www.cnblogs.com/Diryboy/" target=_blank><u><font color=#0000ff>DiryBoy</font></u></a>提醒），方法如下：
    <ul>
        <li>用文本编辑器打开%AppData%\Microsoft\VisualStudio\9.0\VsFontLk.dat；
        <li>将0804一行修改为需要的中文字体，格式为&#8220;0804|中文字体名称&#8221;，比如&#8220;0804|微软雅黑&#8221;； </li>
    </ul>
    </li>
</ul>
<img src ="http://www.cppblog.com/Hero/aggbug/101900.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-11-25 12:01 <a href="http://www.cppblog.com/Hero/archive/2009/11/25/101900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件项目版本号的命名规则及格式介绍</title><link>http://www.cppblog.com/Hero/archive/2009/11/17/101199.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Tue, 17 Nov 2009 06:14:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/11/17/101199.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/101199.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/11/17/101199.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/101199.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/101199.html</trackback:ping><description><![CDATA[版本控制比较普遍的 3 种命名格式 : <br><br>　　一、GNU 风格的版本号命名格式 : <br><br>　　主版本号 . 子版本号 [. 修正版本号 [. 编译版本号 ]] <br><br>　　英文对照 : Major_Version_Number.Minor_Version_Number[.Revision_Number[.Build_Number]] <br><br>　　示例 : 1.2.1, 2.0, 5.0.0 build-13124 <br><br>　　二、Windows 风格的版本号命名格式 : <br><br>　　主版本号 . 子版本号 [ 修正版本号 [. 编译版本号 ]] <br><br>　　英文对照 : Major_Version_Number.Minor_Version_Number[Revision_Number[.Build_Number]] <br><br>　　示例: 1.21, 2.0 <br><br>　　三、.Net Framework 风格的版本号命名格式: <br><br>　　主版本号.子版本号[.编译版本号[.修正版本号]] <br><br>　　英文对照: Major_Version_Number.Minor_Version_Number[.Build_Number[.Revision_Number]] <br><br>　　版本号由二至四个部分组成：主版本号、次版本号、内部版本号和修订号。主版本号和次版本号是必选的；内部版本号和修订号是可选的，但是如果定义了修订号部分，则内部版本号就是必选的。所有定义的部分都必须是大于或等于 0 的整数。 <br><br>　　应根据下面的约定使用这些部分： <br><br>　　Major ：具有相同名称但不同主版本号的程序集不可互换。例如，这适用于对产品的大量重写，这些重写使得无法实现向后兼容性。 <br><br>　　Minor ：如果两个程序集的名称和主版本号相同，而次版本号不同，这指示显著增强，但照顾到了向后兼容性。例如，这适用于产品的修正版或完全向后兼容的新版本。 <br><br>　　Build ：内部版本号的不同表示对相同源所作的重新编译。这适合于更改处理器、平台或编译器的情况。 <br><br>　　Revision ：名称、主版本号和次版本号都相同但修订号不同的程序集应是完全可互换的。这适用于修复以前发布的程序集中的安全漏洞。 <br><br>　　程序集的只有内部版本号或修订号不同的后续版本被认为是先前版本的修补程序 (Hotfix) 更新。 <br><br>　　版本号管理策略 <br><br>　　一、 GNU 风格的版本号管理策略： <br><br>　　1．项目初版本时 , 版本号可以为 0.1 或 0.1.0, 也可以为 1.0 或 1.0.0, 如果你为人很低调 , 我想你会选择那个主版本号为 0 的方式 ; <br><br>　　2．当项目在进行了局部修改或 bug 修正时 , 主版本号和子版本号都不变 , 修正版本号加 1; <br><br>　　3. 当项目在原有的基础上增加了部分功能时 , 主版本号不变 , 子版本号加 1, 修正版本号复位为 0, 因而可以被忽略掉 ; <br><br>　　4．当项目在进行了重大修改或局部修正累积较多 , 而导致项目整体发生全局变化时 , 主版本号加 1; <br><br>　　5．另外 , 编译版本号一般是编译器在编译过程中自动生成的 , 我们只定义其格式 , 并不进行人为控制 . <br><br>　　二、 Window 下的版本号管理策略： <br><br>　　1．目初版时 , 版本号为 1.0 或 1.00; <br><br>　　2. 当项目在进行了局部修改或 bug 修正时，主版本号和子版本号都不变 , 修正版本号加 1; <br><br>　　3. 当项目在原有的基础上增加了部分功能时 , 主版本号不变 , 子版本号加 1, 修正版本号复位为 0, 因而可以被忽略掉 ; <br><br>　　4. 当项目在进行了重大修改或局部修正累积较多 , 而导致项目整体发生全局变化时 , 主版本号加 1; <br><br>　　5. 另外 , 编译版本号一般是编译器在编译过程中自动生成的 , 我们只定义其格式 , 并不进行人为控制 . <br><br>　　另外 , 还可以在版本号后面加入 Alpha, Beta, Gamma, Current, RC (Release Candidate), Release, Stable 等后缀 , 在这后缀后面还可以加入 1 位数字的版本号 . <br><br>　　对于用户来说 , 如果某个软件的主版本号进行了升级 , 用户还想继续那个软件 , 则发行软件的公司一般要对用户收取升级费用 ; 而如果子版本号或修正版本号发生了升级 , 一般来说是免费的 . <br>
<p>附： alphal 内部测试版 <br>　　 beta 外部测试版 <br>　　 demo 演示版 <br>　　 Enhance 增强版或者加强版 属于正式版 <br>　　 Free 自由版 <br>　　 Full version 完全版 属于正式版 <br>　　 shareware 共享版 <br>　　 Release 发行版 有时间限制 <br>　　 Upgrade 升级版 <br>　　 Retail 零售版 <br>　　 Cardware 属共享软件的一种，只要给作者回复一封电邮或明信片即可。（有的作者并由此提供注册码等），目前这种形式已不多见。 <br>　　 Plus 属增强版，不过这种大部分是在程序界面及多媒体功能上增强。 <br>　　 Preview 预览版 <br>　　 Corporation &amp; Enterprise 企业版 <br>　　 Standard 标准版 <br>　　 Mini 迷你版也叫精简版只有最基本的功能 <br>　　 Premium — 贵价版 <br>　　 Professional — 专业版 <br>　　 Express — 特别版 <br>　　 Deluxe — 豪华版 <br>　　 Regged — 已注册版 <br>　　 CN — 简体中文版 <br>　　 CHT — 繁体中文版 <br>　　 EN — 英文版 <br>　　 Multilanguage — 多语言版 <br><br>　　注释： <br><br>　　&#945;版 <br><br>　　此版本表示该软件仅仅是一个初步完成品，通常只在软件开发者内部交流，也有很少一部分发布给专业测试人员。一般而言，该版本软件的 bug 较多，普通用户最好不要安装。 <br><br>　　&#946;（beta）版 <br><br>　　该版本相对于&#945;版已有了很大的改进，消除了严重的错误，但还是存在着一些缺陷，需要经过大规模的发布测试来进一步消除。这一版本通常由软件公司免费发布，用户可从相关的站点下载。通过一些专业爱好者的测试，将结果反馈给开发者，开发者们再进行有针对性的修改。该版本也不适合一般用户安装。 <br><br>　　&#947;版 <br><br>　　该版本已经相当成熟了，与即将发行的正式版相差无几，如果用户实在等不及了，尽可以装上一试。 <br><br>　　trial（试用版） <br><br>　　试用版软件在最近的几年里颇为流行，主要是得益于互联网的迅速发展。该版本软件通常都有时间限制，过期之后用户如果希望继续使用，一般得交纳一定的费用进行注册或购买。有些试用版软件还在功能上做了一定的限制。 <br><br>　　unregistered（未注册版） <br><br>　　未注册版与试用版极其类似，只是未注册版通常没有时间限制，在功能上相对于正式版做了一定的限制，例如绝大多数网络电话软件的注册版和未注册版，两者之间在通话质量上有很大差距。还有些虽然在使用上与正式版毫无二致，但是动不动就会弹出一个恼人的消息框来提醒你注册，如看图软件 acdsee 、智能陈桥汉字输入软件等。 <br><br>　　demo版 <br><br>　　也称为演示版，在非正式版软件中，该版本的知名度最大。 demo 版仅仅集成了正式版中的几个功能，颇有点像 unregistered 。不同的是， demo 版一般不能通过升级或注册的方法变为正式版。 <br><br>　　以上是软件正式版本推出之前的几个版本，&#945;、&#946;、&#947;可以称为测试版，大凡成熟软件总会有多个测试版，如 windows 98 的&#946;版，前前后后将近有 10 个。这么多的测试版一方面为了最终产品尽可能地满足用户的需要，另一方面也尽量减少了软件中的 bug 。而 trial 、 unregistered 、 demo 有时统称为演示版，这一类版本的广告色彩较浓，颇有点先尝后买的味道，对于普通用户而言自然是可以免费尝鲜了。 <br><br>　　正式版　不同类型的软件的正式版本通常也有区别。 <br><br>　　release <br><br>　　该版本意味&#8220;最终释放版&#8221;，在出了一系列的测试版之后，终归会有一个正式版本，对于用户而言，购买该版本的软件绝对不会错。该版本有时也称为标准版。 一般情况下， release 不会以单词形式出现在软件封面上，取而代之的是符号 (r) ，如 windows nt(r) 4.0 、 ms-dos(r) 6.22 等。 <br><br>　　registered <br><br>　　很显然，该版本是与 unregistered 相对的注册版。注册版、 release 和下面所讲的 standard 版一样，都是软件的正式版本，只是注册版软件的前身有很大一部分是从网上下载的。 <br><br>　　standard <br><br>　　这是最常见的标准版，不论是什么软件，标准版一定存在。标准版中包含了该软件的基本组件及一些常用功能，可以满足一般用户的需求。其价格相对高一级版本而言还是&#8220;平易近人&#8221;的。 <br><br>　　deluxe <br><br>　　顾名思义即为&#8220;豪华版&#8221;。豪华版通常是相对于标准版而言的，主要区别是多了几项功能，价格当然会高出一大块，不推荐一般用户购买。此版本通常是为那些追求&#8220;完美&#8221;的专业用户所准备的。 <br><br>　　reference <br><br>　　该版本型号常见于百科全书中，比较有名的是微软的 encarta 系列。 reference 是最高级别，其包含的主题、图像、影片剪辑等相对于 standard 和 deluxe 版均有大幅增加，容量由一张光盘猛增至三张光盘，并且加入了很强的交互功能，当然价格也不菲。可以这么说，这一版本的百科全书才能算是真正的百科全书，也是发烧友们收藏的首选。 <br><br>　　professional（专业版） <br><br>　　专业版是针对某些特定的开发工具软件而言的。专业版中有许多内容是标准版中所没有的，这些内容对于一个专业的软件开发人员来说是极为重要的。如微软的 visual foxpro 标准版并不具备编译成可执行文件的功能，这对于一个完整的开发项目而言显然是无法忍受的，若客户机上没有 foxpro 将不能使用。如果用专业版就没有这个问题了。 <br><br>　　enterprise（企业版） <br><br>　　企业版是开发类软件中的极品（相当于百科全书中的 reference 版）。拥有一套这种版本的软件可以毫无障碍地开发任何级别的应用软件。如著名的 visual c++ 的企业版相对于专业版来说增加了几个附加的特性，如 sql 调试、扩展的存储过程向导、支持 as/400 对 ole db 的访问等。而这一版本的价格也是普通用户无法接受的。如微软的 visual studios 6.0 enterprise 中文版的价格为 23000 元。 <br><br>　　其他版本　除了以上介绍的一些版本外，还有一些专有版本名称。 <br><br>　　update（升级版） <br><br>　　升级版的软件是不能独立使用的，该版本的软件在安装过程中会搜索原有的正式版，如果不存在，则拒绝执行下一步。如 microsoft office 2000 升级版、 windows 9x 升级版等等。 <br><br>　　OEM版 <br><br>　　OEM版通常是捆绑在硬件中而不单独销售的版本。将自己的产品交给别的公司去卖，保留自己的著作权，双方互惠互利，一举两得。 <br><br>　　单机（网络）版 <br><br>　　网络版在功能、结构上远比单机版复杂，如果留心一下软件的报价，你就会发现某些软件单机版和网络版的价格相差非常大，有些网络版甚至多一个客户端口就要加不少钱。 <br><br>　　普及版 <br><br>　　该版本有时也会被称为共享版，其特点是价格便宜（有些甚至完全免费）、功能单一、针对性强（当然也有占领市场、打击盗版等因素）。与试用版不同的是，该版本的软件一般不会有时间上的限制。当然，如果用户想升级，最好还是去购买正式版。 <br><br>　　以上是一些常见软件版本的简要介绍，随着软件市场行为的变化，现在也出现了一些新的版本命名方式，比如windows xp中的xp是取自于experience中的第二、第三个字母。希望以上内容能够对大家的购买、使用和下载软件有所帮助。 <br><br>　　基于商业上考虑，很多的软件都不是非常严谨的遵循这个规则的。最有名的就是微软了。例如他的 NT 系列版本。大家比较熟悉的是从 NT 4.0 开始的。 99 年推出了 windows 2000 ， 2001 年退出了 windows xp ， 2003 年推出了 windows 2003 ，乍一看版本区别蛮大的，但是看他们的内部版本号就会发现，变化其实并不大，只是界面变化的大了而已。这是软件公司经常干的事情。 Window 2000 的版本号是 NT 5.0 ， windows xp 的版本号是 NT 5.1 ， windows 2003 的版本号是 NT 5.2 ，而现在的 longhorn 才是真正的 NT 6.0 （印象中是，不敢确认）。这样就可以持续的赚广大客户的钱。毕竟人的眼睛看得东西是最直观的，所以给人感觉也是变化最大的。</p>
<img src ="http://www.cppblog.com/Hero/aggbug/101199.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-11-17 14:14 <a href="http://www.cppblog.com/Hero/archive/2009/11/17/101199.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javascript [转载]</title><link>http://www.cppblog.com/Hero/archive/2009/08/14/93310.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Fri, 14 Aug 2009 06:35:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/08/14/93310.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/93310.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/08/14/93310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/93310.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/93310.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 今天在网上看到一篇介绍javascript的文章，文采真是没的说，能将本来枯燥的程序讲述的如此酣畅淋漓实在让人佩服！ 来源&nbsp; ：http://blog.csdn.net/gisfarmer/archive/2009/02/13/3885515.aspx&nbsp;引子 &nbsp;&nbsp;&nbsp; 编程世界里只存在两种基本元素，一个是数据，一个是代码。编程世界就是在数...&nbsp;&nbsp;<a href='http://www.cppblog.com/Hero/archive/2009/08/14/93310.html'>阅读全文</a><img src ="http://www.cppblog.com/Hero/aggbug/93310.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-08-14 14:35 <a href="http://www.cppblog.com/Hero/archive/2009/08/14/93310.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python获取文件夹大小（1）</title><link>http://www.cppblog.com/Hero/archive/2009/07/28/91470.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Tue, 28 Jul 2009 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/07/28/91470.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/91470.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/07/28/91470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/91470.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/91470.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%; font-family: courier new;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">!/usr/bin/env&nbsp;python</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;">#<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getDirSize.py</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copyright&nbsp;2009&nbsp;Hiro&nbsp;&lt;wangzhaoren@gmail.com&gt;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and/or&nbsp;modify</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;as&nbsp;published&nbsp;by</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2&nbsp;of&nbsp;the&nbsp;License,&nbsp;or</span><span style="color: #008000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.</span><span style="color: #008000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,</span><span style="color: #008000;"><br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of</span><span style="color: #008000;"><br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the</span><span style="color: #008000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.</span><span style="color: #008000;"><br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License</span><span style="color: #008000;"><br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software</span><span style="color: #008000;"><br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,</span><span style="color: #008000;"><br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MA&nbsp;02110-1301,&nbsp;USA.</span><span style="color: #008000;"><br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;"><br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;os<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">from</span><span style="color: #000000;">&nbsp;os.path&nbsp;</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;join,&nbsp;getsize<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;getDirSize(&nbsp;dir&nbsp;):<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;0L<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;root,&nbsp;dirs,&nbsp;files&nbsp;</span><span style="color: #0000ff;">in</span><span style="color: #000000;">&nbsp;os.walk(dir):<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;sum(&nbsp;[getsize(join(root,&nbsp;name))&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;name&nbsp;</span><span style="color: #0000ff;">in</span><span style="color: #000000;">&nbsp;files]&nbsp;)<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;size<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;main():<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;filesize&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;getDirSize(&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">/home/wangzr</span><span style="color: #800000;">"</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">print</span><span style="color: #000000;">&nbsp;(&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">there&nbsp;are&nbsp;%0.3f</span><span style="color: #800000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">%</span><span style="color: #000000;">(filesize</span><span style="color: #000000;">/</span><span style="color: #000000;">1024</span><span style="color: #000000;">/</span><span style="color: #000000;">1024</span><span style="color: #000000;">),&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">Mb&nbsp;in&nbsp;/home/wangzr</span><span style="color: #800000;">"</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;0<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">__name__</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">__main__</span><span style="color: #800000;">'</span><span style="color: #000000;">:&nbsp;main()<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;"></span></div>
<br><img src ="http://www.cppblog.com/Hero/aggbug/91470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-07-28 14:07 <a href="http://www.cppblog.com/Hero/archive/2009/07/28/91470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python获取文件夹大小（2）</title><link>http://www.cppblog.com/Hero/archive/2009/07/28/91471.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Tue, 28 Jul 2009 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/07/28/91471.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/91471.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/07/28/91471.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/91471.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/91471.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%; font-family: courier new;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">!/usr/bin/env&nbsp;python</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;">#<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getDirSize2.py</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copyright&nbsp;2009&nbsp;Hiro&nbsp;&lt;wangzhaoren@gmail.com&gt;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and/or&nbsp;modify</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;as&nbsp;published&nbsp;by</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2&nbsp;of&nbsp;the&nbsp;License,&nbsp;or</span><span style="color: #008000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.</span><span style="color: #008000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,</span><span style="color: #008000;"><br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of</span><span style="color: #008000;"><br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the</span><span style="color: #008000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.</span><span style="color: #008000;"><br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License</span><span style="color: #008000;"><br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software</span><span style="color: #008000;"><br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,</span><span style="color: #008000;"><br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MA&nbsp;02110-1301,&nbsp;USA.</span><span style="color: #008000;"><br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;"><br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;os<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;"></span><span style="color: #008000;">#</span><span style="color: #008000;">from&nbsp;os&nbsp;import&nbsp;listdir</span><span style="color: #008000;"><br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;"><br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;getDirSize(&nbsp;source&nbsp;)&nbsp;:<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;0L<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;os.path.isfile(&nbsp;source&nbsp;)&nbsp;:<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;os.stat(&nbsp;source&nbsp;)[</span><span style="color: #000000;">6</span><span style="color: #000000;">]<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">elif</span><span style="color: #000000;">&nbsp;os.path.isdir(&nbsp;source&nbsp;)&nbsp;:<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;src&nbsp;</span><span style="color: #0000ff;">in</span><span style="color: #000000;">&nbsp;os.listdir(&nbsp;source&nbsp;)&nbsp;:<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srcpath&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;os.path.join(&nbsp;source,&nbsp;src&nbsp;)<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">print</span><span style="color: #000000;">&nbsp;srcpath<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;getDirSize(&nbsp;srcpath&nbsp;)<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;size<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;main():<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;dirname&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;r</span><span style="color: #800000;">"</span><span style="color: #800000;">/home/wangzr</span><span style="color: #800000;">"</span><span style="color: #000000;"><br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">print</span><span style="color: #000000;">&nbsp;getDirSize(&nbsp;dirname&nbsp;)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">1024</span><span style="color: #000000;"><br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;0<br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">__name__</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">__main__</span><span style="color: #800000;">'</span><span style="color: #000000;">:&nbsp;main()<br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;"></span></div>
<br><img src ="http://www.cppblog.com/Hero/aggbug/91471.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-07-28 14:07 <a href="http://www.cppblog.com/Hero/archive/2009/07/28/91471.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载] python中文编码问题</title><link>http://www.cppblog.com/Hero/archive/2009/07/24/91038.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Fri, 24 Jul 2009 06:30:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/07/24/91038.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/91038.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/07/24/91038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/91038.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/91038.html</trackback:ping><description><![CDATA[<div class=tit>&nbsp;</div>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <div class=abstract>
            <p>Unicode 是一个系统，用来表示世界上所有不同语言的字符。当 <span class=application>Python</span> 解析一个 <span class=acronym>XML</span> 文档时，所有的数据都是以unicode的形式保存在内存中的。</p>
            </div>
            <p>一会儿你就会了解，但首先，先看一些背景知识。</p>
            <p><strong>历史注解. </strong>在 unicode 之前，对于每一种语言都存在独立的字符编码系统，每个系统都使用相同的数字(0-255)来表示这种语言的字符。一些语言 (像俄语) 对于如何表示相同的字符还有几种有冲突的标准；另一些语言 (像日语) 拥有太多的字符，需要多个字符集。在系统之间进行文档交流是困难的，因为对于一台计算机来说，没有方法可以识别出文档的作者使用了哪种编码模式；计算机看 到的只是数字，并且这些数字可以表示不同的东西。接着考虑到试图将这些 (采用不同编码的) 文档存放到同一个地方 (比如在同一个数据库表中)；你需要在每段文本的旁边保存字符的编码，并且确保在传递文本的同时将编码也进行传递。接着考虑多语言文档，即在同一文档中使 用了不同语言的字符。(比较有代表性的是使用转义符来进行模式切换；噗，我们处于俄语 koi8-r 模式，所以字符 241 表示这个；噗，现在我们处于 Mac 希腊语模式，所以字符 241 表示其它什么。等等。) 这些就是 unicode 被设计出来要解决的问题。</p>
            <p>为了解决这些问题，unicode 用一个 2 字节数字表示每个字符，从 0 到 65535。<sup>[<a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#ftn.d0e23957" name=d0e23957><u><font color=#0000ff>8</font></u></a>]</sup> 每个 2 字节数字表示至少在一种世界语言中使用的一个唯一字符。(在多种语言中都使用的字符具有相同的数字码。) 这样就确保每个字符一个数字，并且每个数字一个字符。Unicode 数据永远不会模棱两可。</p>
            <p>当然，仍然还存在着所有那些遗留的编码系统的情况。例如，7 位 <span class=acronym>ASCII</span>，它可以将英文字符存诸为从 0 到 127 的数值。(65 是大写字母 &#8220;<span class=quote><tt class=literal>A</tt></span>&#8221;，97 是小写字母 &#8220;<span class=quote><tt class=literal>a</tt></span>&#8221;，等等。) 英语有着非常简单的字母表，所以它可以完全用 7 位 <span class=acronym>ASCII</span> 来表示。像法语、西班牙语和德语之类的西欧语言都使用叫做 ISO-8859-1 的编码系统 (也叫做&#8220;<span class=quote>latin-1</span>&#8221;)，它使用 7 位 <span class=acronym>ASCII</span> 字符表示从 0 到 127 的数字，但接着扩展到了 128-255 的范围来表示像 n 上带有一个波浪线(241)，和 u 上带有两个点(252)的字符。Unicode 在 0 到 127 上使用了同 7 位 <span class=acronym>ASCII</span> 码一样的字符表，在 128 到 255上同 ISO-8859-1 一样，接着使用剩余的数字，256 到 65535，扩展到表示其它语言的字符。</p>
            <p>在 处理 unicode 数据时，在某些地方你可能需要将数据转换回这些遗留编码系统之一。例如，为了同其它一些计算机系统集成，这些系统期望它的数据使用一种特定的单字节编码模 式，或将数据打印输出到一个不识别 unicode 的终端或打印机。或将数据保存到一个明确指定编码模式的 <span class=acronym>XML</span> 文档中。</p>
            <p>在了解这个注解之后，让我们回到 <span class=application>Python</span>上来。</p>
            <p>从 2.0 版开始，<span class=application>Python</span> 整个语言都已经支持 unicode。<span class=acronym>XML</span> 包使用 unicode 来保存所有解析了的 <span class=acronym>XML</span> 数据，而且你可以在任何地方使用 unicode。</p>
            <div class=example><a name=d0e24013></a>
            <h3 class=title>例 9.13. unicode 介绍</h3>
            <pre class=screen><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>s = u<span class=pystring>'Dive in'</span></span>            <a name=kgp.unicode.1.1></a><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>s</span><br><span class=computeroutput>u'Dive in'</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>print</span> s</span>                   <a name=kgp.unicode.1.2></a><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0><br><span class=computeroutput>Dive in</span></pre>
            <div class=calloutlist>
            <table summary="Callout list" border=0>
                <tbody>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.1.1"><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>为了创建一个 unicode 字符串而不是通常的 <span class=acronym>ASCII</span> 字符串，要在字符串前面加上字母 &#8220;<span class=quote><tt class=literal>u</tt></span>&#8221;。注意这个特殊的字符串没有任何非 <span class=acronym>ASCII</span> 的字符。这样很好；unicode 是 <span class=acronym>ASCII</span> 的一个超集 (一个非常大的超集)，所以任何正常的 <span class=acronym>ASCII</span> 都可以以 unicode 形式保存起来。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.1.2"><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>在打印字符串时，<span class=application>Python</span> 试图将字符串转换为你的默认编码，通常是 <span class=acronym>ASCII</span> 。(过会儿有更详细的说明。) 因为组成这个 unicode 字符串的字符都是 <span class=acronym>ASCII</span> 字符，打印结果与打印正常的 <span class=acronym>ASCII</span> 字符串是一样的；转换是无缝的，而且如果你没有注意到 <tt class=varname>s</tt> 是一个 unicode 字符串的话，你永远也不会注意到两者之间的差别。</td>
                    </tr>
                </tbody>
            </table>
            </div>
            </div>
            <div class=example><a name=d0e24080></a>
            <h3 class=title>例 9.14. 存储非 <span class=acronym>ASCII</span> 字符</h3>
            <pre class=screen><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>s = u<span class=pystring>'La Pe\xf1a'</span></span>         <a name=kgp.unicode.2.1></a><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>print</span> s</span>                   <a name=kgp.unicode.2.2></a><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0><br><span class=traceback>Traceback (innermost last):<br>  File "&lt;interactive input&gt;", line 1, in ?<br>UnicodeError: ASCII encoding error: ordinal not in range(128)</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>print</span> s.encode(<span class=pystring>'latin-1'</span>)</span> <a name=kgp.unicode.2.3></a><img height=12 alt=3 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/3.png" width=12 border=0><br><span class=computeroutput>La Pe&#241;a</span></pre>
            <div class=calloutlist>
            <table summary="Callout list" border=0>
                <tbody>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.2.1"><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>unicode 真正的优势，理所当然的是它保存非 <span class=acronym>ASCII</span> 字符的能力，例如西班牙语的 &#8220;<span class=quote><tt class=literal>&#241;</tt></span>&#8221;(<tt class=literal>n</tt> 上带有一个波浪线)。用来表示波浪线 n 的 unicode 字符编码是十六进制的 <tt class=literal>0xf1</tt> (十进制的241)，你可以像这样输入：<tt class=literal>\xf1</tt>。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.2.2"><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>还记得我说过 <tt class=function>print</tt> 函数会尝试将 unicode 字符串转换为 <span class=acronym>ASCII</span> 从而打印它吗？嗯，在这里将不会起作用，因为你的 unicode 字符串包含非 <span class=acronym>ASCII</span> 字符，所以 <span class=application>Python</span> 会引发 <tt class=errorname>UnicodeError</tt> 异常。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.2.3"><img height=12 alt=3 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/3.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>这儿就是将 unicode 转换为其它编码模式起作用的地方。<tt class=varname>s</tt> 是一个 unicode 字符串，但 <tt class=function>print</tt> 只能打印正常的字符串。为了解决这个问题，我们调用 <tt class=function>encode</tt> 方法 (它可以用于每个 unicode 字符串) 将 unicode 字符串转换为指定编码模式的正常字符串。我们向此函数传入一个参数。在本例中，我们使用 <tt class=literal>latin-1</tt> (也叫 <tt class=literal>iso-8859-1</tt>)，它包括带波浪线的 n (然而缺省的 <span class=acronym>ASCII</span> 编码模式不包括，因为它只包含数值从 0 到 127 的字符)。</td>
                    </tr>
                </tbody>
            </table>
            </div>
            </div>
            <p>还记得我说过：需要从一个 unicode 得到一个正常字符串时，<span class=application>Python</span> 通常默认将 unicode 转换成 <span class=acronym>ASCII</span> 吗？嗯，这个默认编码模式是一个可以定制的选项。</p>
            <div class=example><a name=d0e24181></a>
            <h3 class=title>例 9.15. <tt class=filename>sitecustomize.py</tt></h3>
            <pre class=programlisting><span class=pycomment># sitecustomize.py                   </span><a name=kgp.unicode.3.1></a><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0><br><span class=pycomment># this file can be anywhere in your Python path,</span><br><span class=pycomment># but it usually goes in ${pythondir}/lib/site-packages/</span><br><span class=pykeyword>import</span> sys<br>sys.setdefaultencoding(<span class=pystring>'iso-8859-1'</span>) <a name=kgp.unicode.3.2></a><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></pre>
            <div class=calloutlist>
            <table summary="Callout list" border=0>
                <tbody>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.3.1"><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0></a></td>
                        <td vAlign=top align=left><tt class=filename>sitecustomize.py</tt> 是一个特殊的脚本；<span class=application>Python</span> 会在启动的时候导入它，所以在其中的任何代码都将自动运行。就像注解中提到的那样，它可以放在任何地方 (只要 <tt class=literal>import</tt> 能够找到它)，但是通常它位于 <span class=application>Python</span> 的<tt class=filename>lib</tt> 目录的 <tt class=filename>site-packages</tt> 目录中。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.3.2"><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>嗯，<tt class=function>setdefaultencoding</tt> 函数设置默认编码。<span class=application>Python</span> 会在任何需要将 unicode 字符串自动转换为正规字符串的地方，使用这个编码模式。</td>
                    </tr>
                </tbody>
            </table>
            </div>
            </div>
            <div class=example><a name=d0e24221></a>
            <h3 class=title>例 9.16. 设置默认编码的效果</h3>
            <pre class=screen><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>import</span> sys</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>sys.getdefaultencoding()</span> <a name=kgp.unicode.4.1></a><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0><br><span class=computeroutput>'iso-8859-1'</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>s = u<span class=pystring>'La Pe\xf1a'</span></span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>print</span> s</span>                  <a name=kgp.unicode.4.2></a><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0><br><span class=computeroutput>La Pe&#241;a</span></pre>
            <div class=calloutlist>
            <table summary="Callout list" border=0>
                <tbody>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.4.1"><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>这个例子假设你已经按前一个例子中的改动对 <tt class=filename>sitecustomize.py</tt> 文件做了修改，并且已经重启了 <span class=application>Python</span>。如果你的默认编码还是 <tt class=literal>'ascii'</tt>，可能你就没有正确设置 <tt class=filename>sitecustomize.py</tt> 文件，或者是没有重新启动 <span class=application>Python</span>。默认的编码只能在 <span class=application>Python</span> 启动的时候改变；之后就不能改变了。(由于一些我们现在不会仔细研究的古怪的编程技巧，你甚至不能在 <span class=application>Python</span> 启动之后调用 <tt class=function>sys.setdefaultencoding</tt> 函数。仔细研究 <tt class=filename>site.py</tt>，并搜索 &#8220;<span class=quote><tt class=literal>setdefaultencoding</tt></span>&#8221; 去发现为什么吧。)</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.4.2"><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>现在默认的编码模式已经包含了你在字符串中使用的所有字符，<span class=application>Python</span> 对字符串的自动强制转换和打印就不存在问题了。</td>
                    </tr>
                </tbody>
            </table>
            </div>
            </div>
            <div class=example><a name=d0e24296></a>
            <h3 class=title>例 9.17. 指定<tt class=filename>.py</tt>文件的编码</h3>
            <p>如果你打算在你的 <span class=application>Python</span> 代码中保存非 <span class=acronym>ASCII</span> 字符串，你需要在每个文件的顶端加入编码声明来指定每个 <tt class=filename>.py</tt> 文件的编码。这个声明定义了 <tt class=filename>.py</tt> 文件的编码为 UTF-8：</p>
            <pre class=programlisting><span class=pycomment>#!/usr/bin/env python</span><br><span class=pycomment># -*- coding: UTF-8 -*-</span></pre>
            </div>
            <p>现在，想想 <span class=acronym>XML</span> 中的编码应该是怎样的呢？不错，每一个 <span class=acronym>XML</span> 文档都有指定的编码。重复一下，ISO-8859-1 是西欧语言存放数据的流行编码方式。KOI8-R 是俄语流行的编码方式。编码――如果指定了的话――都在 <span class=acronym>XML</span> 文档的首部。</p>
            <div class=example><a name=d0e24329></a>
            <h3 class=title>例 9.18. <tt class=filename>russiansample.xml</tt></h3>
            <pre class=screen><span class=computeroutput><br>&lt;?xml version="1.0" encoding="koi8-r"?&gt;       </span><a name=kgp.unicode.5.1></a><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0><span class=computeroutput><br>&lt;preface&gt;<br>&lt;title&gt;Предисловие&lt;/title&gt;                    </span><a name=kgp.unicode.5.2></a><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0><span class=computeroutput><br>&lt;/preface&gt;</span></pre>
            <div class=calloutlist>
            <table summary="Callout list" border=0>
                <tbody>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.5.1"><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>这是从一个真实的俄语 <span class=acronym>XML</span> 文档中提取出来的示例；它就是这本书俄语翻译版的一部分。注意，编码 <tt class=literal>koi8-r</tt> 是在首部指定的。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.5.2"><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>这些是古代斯拉夫语的字符，就我所知，它们用来拼写俄语单词&#8220;<span class=quote>Preface</span>&#8221;。如果你在一个正常文本编辑器中打开这个文件，这些字符非常像乱码，因为它们使用了 <tt class=literal>koi8-r</tt> 编码模式进行编码，但是却以 <tt class=literal>iso-8859-1</tt> 编码模式进行显示。</td>
                    </tr>
                </tbody>
            </table>
            </div>
            </div>
            <div class=example><a name=d0e24364></a>
            <h3 class=title>例 9.19. 解析 <tt class=filename>russiansample.xml</tt></h3>
            <pre class=screen><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>from</span> xml.dom <span class=pykeyword>import</span> minidom</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>xmldoc = minidom.parse(<span class=pystring>'russiansample.xml'</span>)</span> <a name=kgp.unicode.6.1></a><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>title = xmldoc.getElementsByTagName(<span class=pystring>'title'</span>)[0].firstChild.data</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>title</span>                                       <a name=kgp.unicode.6.2></a><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0><br><span class=computeroutput>u'\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435'</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>print</span> title</span>                                 <a name=kgp.unicode.6.3></a><img height=12 alt=3 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/3.png" width=12 border=0><br><span class=traceback>Traceback (innermost last):<br>  File "&lt;interactive input&gt;", line 1, in ?<br>UnicodeError: ASCII encoding error: ordinal not in range(128)</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>convertedtitle = title.encode(<span class=pystring>'koi8-r'</span>)</span>     <a name=kgp.unicode.6.4></a><img height=12 alt=4 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/4.png" width=12 border=0><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput>convertedtitle</span><br><span class=computeroutput>'\xf0\xd2\xc5\xc4\xc9\xd3\xcc\xcf\xd7\xc9\xc5'</span><br><tt class=prompt>&gt;&gt;&gt; </tt><span class=userinput><span class=pykeyword>print</span> convertedtitle</span>                        <a name=kgp.unicode.6.5></a><img height=12 alt=5 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/5.png" width=12 border=0><br><span class=computeroutput>Предисловие</span></pre>
            <div class=calloutlist>
            <table summary="Callout list" border=0>
                <tbody>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.6.1"><img height=12 alt=1 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/1.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>我假设在这里你将前一个例子以 <tt class=filename>russiansample.xml</tt> 为名保存在当前目录中。也出于完整性的考虑，我假设你已经删除了 <tt class=filename>sitecustomize.py</tt> 文件，将缺省编码改回到 <tt class=literal>'ascii'</tt>，或至少将 <tt class=function>setdefaultencoding</tt> 一行注释起来了。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.6.2"><img height=12 alt=2 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/2.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>注意 <tt class=sgmltag-element>title</tt> 标记 (现在在 <tt class=varname>title</tt> 变量中，上面那一长串 <span class=application>Python</span> 函数我们暂且跳过，下一节再解释)――在 <span class=acronym>XML</span> 文档的 <tt class=sgmltag-element>title</tt> 元素中的文本数据是以 unicode 保存的。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.6.3"><img height=12 alt=3 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/3.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>直接打印 title 是不可能的，因为这个 unicode 字符串包含了非 <span class=acronym>ASCII</span> 字符，所以 <span class=application>Python</span> 不能把它转换为 <span class=acronym>ASCII</span>，因为它无法理解。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.6.4"><img height=12 alt=4 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/4.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>但是，你能够显式地将它转换为 <tt class=literal>koi8-r</tt>，在本例中，我们得到一个 (正常，非 unicode) 单字节字符的字符串 (<tt class=literal>f0</tt>, <tt class=literal>d2</tt>, <tt class=literal>c5</tt>，等等)，它是初始unicode字符串中字符 <tt class=literal>koi8-r</tt> 编码的版本。</td>
                    </tr>
                    <tr>
                        <td vAlign=top align=left width=12><a href="http://www.woodpecker.org.cn/diveintopython/xml_processing/unicode.html#kgp.unicode.6.5"><img height=12 alt=5 src="http://www.woodpecker.org.cn/diveintopython/images/callouts/5.png" width=12 border=0></a></td>
                        <td vAlign=top align=left>打印 <tt class=literal>koi8-r</tt> 编码的字符串有可能会在你的屏幕上显示为乱码，因为你的 <span class=application>Python</span> <span class=acronym>IDE</span> 将这些字符作为 <tt class=literal>iso-8859-1</tt> 的编码进行解析，而不是 <tt class=literal>koi8-r</tt> 编码。但是，至少它们能打印。 (并且，如果你仔细看，当在一个不支持 unicode 的文本编辑器中打开最初的 <span class=acronym>XML</span> 文档时，会看到相同的乱码。<span class=application>Python</span> 在解析 <span class=acronym>XML</span> 文档时，将它从 <tt class=literal>koi8-r</tt> 转换到了unicode，你只不过是将它转换回来。)</td>
                    </tr>
                </tbody>
            </table>
            </div>
            </div>
            <p>总结一下，如果你以前从没有看到过 unicode，倒是有些唬人，但是在 <span class=application>Python</span> 处理 unicode 数据真是非常容易。如果你的 <span class=acronym>XML</span> 文档都是 7 位的 <span class=acronym>ASCII</span> (像本章中的例子)，你差不多永远都不用考虑 unicode。<span class=application>Python</span> 在进行解析时会将 <span class=acronym>XML</span> 文档中的 <span class=acronym>ASCII</span> 数据转换为 unicode，在任何需要的时候强制转换回为 <span class=acronym>ASCII</span>，你甚至永远都不用注意。但是如果你要处理其它语言的数据，<span class=application>Python</span> 已经准备好了。</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/Hero/aggbug/91038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-07-24 14:30 <a href="http://www.cppblog.com/Hero/archive/2009/07/24/91038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python中文编码问题</title><link>http://www.cppblog.com/Hero/archive/2009/07/24/91037.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Fri, 24 Jul 2009 06:27:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2009/07/24/91037.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/91037.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2009/07/24/91037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/91037.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/91037.html</trackback:ping><description><![CDATA[<fieldset style="FONT-SIZE: 12pt">
<p style="FONT-FAMILY: courier new"><br>Python中有两种字符串，分别是一般的字符串（每个字符用8 bits表示）和Unicode字符串（每个字符用一个或者多个字节表示），它们可以相互转换。关于Unicode，Joel Spolsky 在 <a href="http://www.joelonsoftware.com/articles/Unicode.html" target=_blank><u><font color=#0000ff>The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)</font></u></a> 中有生动的说明，Jason Orendorff 在 <a href="http://www.jorendorff.com/articles/unicode/index.html" target=_blank><u><font color=#0000ff>Unicode for programmers</font></u></a>&nbsp;有着更为全面的描述，在此我就不再多说什么了。来看下面的代码：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 5px; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 5px; MARGIN: 5px 20px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: courier new">x = u"中文你好"<br>print s<br></div>
<p style="FONT-FAMILY: courier new">&nbsp;&nbsp;&nbsp; 运行上述代码，Python会给出下面的错误提示</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 5px; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 5px; MARGIN: 5px 20px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: courier new">SyntaxError: Non-ASCII character '\xd6' in file G:\workspace\chinese_problem\src\test.py on line 1, but no encoding declared; see <a href="http://www.python.org/peps/pep-0263.html"><u><font color=#0000ff>http://www.python.org/peps/pep-0263.html</font></u></a> for details<br></div>
<p style="FONT-FAMILY: courier new">&nbsp;&nbsp; 说是遇到非ASCII字符了，并让我们参考pep-0263。PEP-0263（Python Enhancement Proposal）上面说得很清楚了，Python也意识到了国际化问题，并提出了解决方案。根据提案上面的要求，我们有如下代码<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 5px; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 5px; MARGIN: 5px 20px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: courier new">&nbsp;# -*- coding:gb2312 -*- ＃必须在第一行或者第二行<br>print "-------------code 1----------------"<br>a = "中文a我爱你"<br>print a<br>print a.find("我")<br>b = a.replace("爱", "喜欢")<br>print b<br>print "--------------code 2----------------"<br>x = "中文a我爱你"<br>y = unicode(x, "gb2312")<br>print y.encode("gb2312")<br>print y.find(u"我")<br>z = y.replace(u"爱", u"喜欢")<br>print z.encode("gb2312")<br>print "---------------code 3----------------"<br>print y</div>
<p style="FONT-FAMILY: courier new">&nbsp;&nbsp;&nbsp; 程序运行的结果如下：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 5px; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 5px; MARGIN: 5px 20px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: courier new">-------------code 1----------------<br>中文a我爱你<br>5<br>中文a我喜欢你<br>--------------code 2----------------<br>中文a我爱你<br>3<br>中文a我喜欢你<br>---------------code 3----------------<br>Traceback (most recent call last):<br>&nbsp; File "G:\Downloads\eclipse\workspace\p\src\hello.py", line 16, in &lt;module&gt;<br>&nbsp;&nbsp;&nbsp; print y<br>UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)<br></div>
<p style="FONT-FAMILY: courier new">&nbsp;&nbsp;&nbsp;&nbsp; 我们可以看到，通过引入编码声明，我们可以正常地在使用中文了，而且在code 1和2中，控制台也能正确的把中文打印出来。但是，很明显，上面的代码也反映出了不少的问题：<br>&nbsp;&nbsp;&nbsp; 1、code 1 和 2在使用print时采用了不同的方式，1是直接print，而2在print之前先进行编码<br>&nbsp;&nbsp;&nbsp; 2、code 1 和 2中在同样的字符串查找同一个字符&#8220;我&#8221;，得出的结果不一样（分别是5和3）<br>&nbsp;&nbsp;&nbsp; 3、code 3 中直接打印unicode字符串 y时出现错误（这也是为什么code 2中要先进行编码的原因）</p>
<p style="FONT-FAMILY: courier new">&nbsp;&nbsp;&nbsp; 为什么？为什么？我们可以先在脑海中模拟一下我们使用Python的流程：首先，我们先用编辑器编写好源代码，保存成文件。如果源代码中有编码声明而且用的编辑器支持该语法，那么该文件就以相应的编码方式保存在磁盘中。<strong>注意：</strong>编码声明和源文件的编码不一定是一致的，你完全可以在编码声明中声明编码为UTF-8，但是用GB2312来保存源文件。当然，我们不可能自寻烦恼，故意写错，而且好的IDE也能强制保证两者的一致性，但是，如果我们用记事本或者EditPlus等编辑器来编写代码的话，一不小心就会出现这种问题的。<br>&nbsp;&nbsp;&nbsp; 得到一个.py文件后，我们就可以运行它了，这是，我们就把代码交给Python解析器来完成解析工作。解析器读入文件时，先解析文件中的编码声明，我们假设文件的编码为gb2312，那么先将文件中的内容由gb2312转换成Unicode，然后再把这些Unicode转换为UTF-8格式的字节串。完成这一步骤后，解析器把这些UTF-8字节串分段，解析。如果遇到使用Unicode字符串，那么就使用相应的UTF-8字节串创建Unicode字符串，如果程序中使用的是一般的字符串，那么解析器先将UTF-8字节串通过Unicode转换成相应编码（这里就是gb2312编码）的字节串，并用其创建一般的字符串对象。也就是说，Unicode字符串跟一般字符串在内存中的存放格式是不一样的，前者使用UTF-8的格式，后者使用GB2312格式。<br>&nbsp;&nbsp;&nbsp; 好了，内存中的字符串存放格式我们知道了，下面我们要了解print的工作方式。print其实只是负责把内存中相应的字节串交给操作系统，让操作系统相应的程序（譬如cmd窗口）进行显示。这里有两种情况：<br>&nbsp;&nbsp; 1、若字符串是一般的字符串，那么print只需把内存中相应的字节串推送给操作系统。如例子中的code 1。<br>&nbsp;&nbsp;&nbsp; 2、如果字符串是Unicode字符串，那么print在推送之前先进行相应的encode：我们可以显示使用Unicode的encode方法使用合适的编码方式来编码（例子中code 2），否则Python使用默认的编码方式进行编码，也就是ASCII（例子中的code 3）。当然ASCII是不可能正确编码中文的，因此Python报错。<br>&nbsp;&nbsp;&nbsp; 至此，上面的三个问题我们已经可以解析第一和第三个了。至于第二个问题，因为Python中有两种字符串，一般字符串和Unicode字符串，两者都有各自的字符处理方法。对于前者，方法是以字节的方式进行的，而且在GB2312中，每个汉字占用两个字节，因此得到的结果是5；对于后者，也就是Unicode字符串，所有字符都是统一看待的，因此得到3。<br>&nbsp;&nbsp;&nbsp;&nbsp; 虽然上面只提到了控制台程序的中文问题，但是文件读写以及网络传输中出现的中文问题在原理上都是类似的。Unicode的出现可以很大程度上解决软件的国际化问题，同时Python为Unicode提供了极为良好的支持，因此，我建议大家在编写Python的程序时，都统一使用Unicode方式。保存文件时使用UTF-8的编码方式。How to Use UTF-8 with Python有详细的描述。<br>&nbsp;</p>
</fieldset>
<img src ="http://www.cppblog.com/Hero/aggbug/91037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2009-07-24 14:27 <a href="http://www.cppblog.com/Hero/archive/2009/07/24/91037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不上升序列的最小分划</title><link>http://www.cppblog.com/Hero/archive/2008/08/20/59466.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Wed, 20 Aug 2008 13:31:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2008/08/20/59466.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/59466.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2008/08/20/59466.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/59466.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/59466.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: courier new; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">一个著名的定理是这样的：最长上升序列的长度等于不上升序列的最小分划（即将平面上的点分划成尽可能少的不相交的不上升序列）。下面我们就来给出这个定理的证明，在证明的过程中，我们甚至可以得到求具体分割方案的方法。<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">证明：<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">一个显然的结论是最长上升序列的长度小于等于不上升序列的最小分划。因为上升序列中任意两点都不可能属于同一个不上升序列。也就是说，最长上升序列中的所有点分属不同的不上升序列。所以，不上升序列的分划数最少也不会少于最长上升序列的长度。<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">关键的是要证明，最长上升序列的长度大于等于不上升序列的最小分划。我们来构造一个不上升序列的分划。<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">首先在二维Euclid空间中取出所有的满足如下性质的点(x,&nbsp;y)：对于任意的点(x</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">,&nbsp;y</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">)，总满足x</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">&#8804;x&nbsp;</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">&nbsp;y</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">&#8804;y，即(x，y)的&#8220;右上方&#8221;没有别的点。可以证明，取出的点集{(x，y)}是一条不上升序列。因为点集中任意两点(x1,&nbsp;y1)和(x2,&nbsp;y2)总满足x1&#8804;x2&nbsp;</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">&nbsp;y1&#8804;y2且x2&#8804;x1&nbsp;</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">&nbsp;y2&#8804;y1，整理一下即得(x1&#8804;x2)xor(y1&#8804;y2)＝</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">。所以，把这些点按x升序排列后，得到的y相应的成降序。<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">将上面取出的点从空间中去除后，重复上述过程，又可以得到一条新的不上升序列。如此反复&#8230;&#8230;可以得到一个不上升序列的分划(现在还不能肯定这就是最小的分划)。由前面的结论知道，这个分划数必定大于等于最长上升序列的长度。<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">我们对得到的不上升序列分划进行分级，先取出的等级最高，最后取出的等级最低。这样就得到k条分属level1，level2，&#8230;，levelk的不上升序列。<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">这些链上的点满足这样的性质：对于一个属于leveli(i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">k)链上的点(x,&nbsp;y)，必然存在一个属于leveli</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1的点(x</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">,&nbsp;y</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">)，使得x</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">x</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;y</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">y</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">。否则(x,&nbsp;y)在取leveli</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">l链时就会被取走，不应属于leveli。<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">从level1上的一点（x1,&nbsp;y1）开始，取level2的点（x2,&nbsp;y2），x2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">x1&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;y2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">y1，然后取level3的点（x3,&nbsp;y3）&#8230;&#8230;最后必然能取到levelk上的点（xk,&nbsp;yk）。如此得到的序列（x1,&nbsp;y1），（x2,&nbsp;y2），&#8230;，（xk,&nbsp;yk），就是一条上升序列。所以，我们前面得到的不上升序列的分划数就不可能大于最长上升序列长度。<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">这就证明了最长上升序列的长度大于等于不上升序列的最小分划。再加上&#8220;最长上升序列的长度小于等于不上升序列的最小分划&#8221;的结论，就证明了最长上升序列的长度等于不上升序列的最小分划。<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000; FONT-FAMILY: courier new">这个证明的优点在于，它是一个构造性的证明，并且揭示了最长上升序列与不上升序列最小分划之间的较为深刻的关系。<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">根据前面的证明，我们可以很容易得到两种解决本题的方法：<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">（</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">）在给出的二元组中求出最长下降序列的长度（具体实现比较简单，这里就从略了）；<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">（</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">）用类似Topologic排序的方法，构造性的求出不下降序列的最小分割(详细过程见证明)。<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">这两种方法的时间复杂度都是O(n2)的。实际上，本题还能优化到O(nlog2n)级，考虑到题目的规模以及本文的侧重点，这里就不详细展开了。此外，前面讲的方法（</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">），也是求最长双链问题的一个基础。</span></div>
<img src ="http://www.cppblog.com/Hero/aggbug/59466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2008-08-20 21:31 <a href="http://www.cppblog.com/Hero/archive/2008/08/20/59466.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sprintf——用法小结</title><link>http://www.cppblog.com/Hero/archive/2008/08/09/58400.html</link><dc:creator>Hero</dc:creator><author>Hero</author><pubDate>Sat, 09 Aug 2008 11:23:00 GMT</pubDate><guid>http://www.cppblog.com/Hero/archive/2008/08/09/58400.html</guid><wfw:comment>http://www.cppblog.com/Hero/comments/58400.html</wfw:comment><comments>http://www.cppblog.com/Hero/archive/2008/08/09/58400.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Hero/comments/commentRss/58400.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Hero/services/trackbacks/58400.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: courier new; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">sprintf详解&nbsp;<br>转摘声明：选自《CSDN&nbsp;社区电子杂志——C</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">杂志》<br><br><br>在将各种类型的数据构造成字符串时，sprintf&nbsp;的强大功能很少会让你失望。由于sprintf&nbsp;跟printf&nbsp;在用法上几乎一样，只是打印的目的地不同而已，前者打印到字符串中，后者则直接在命令行上输出。这也导致sprintf&nbsp;比printf&nbsp;有用得多。<br><br>sprintf&nbsp;是个变参函数，定义如下：<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sprintf(&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">buffer,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">format&nbsp;[,&nbsp;argument]&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">&nbsp;);<br>除了前两个参数类型固定外，后面可以接任意多个参数。而它的精华，显然就在第二个参数：<br>格式化字符串上。<br><br><br>printf&nbsp;和sprintf&nbsp;都使用格式化字符串来指定串的格式，在格式串内部使用一些以&#8220;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&#8221;开头的格式说明符（format&nbsp;specifications）来占据一个位置，在后边的变参列表中提供相应的变量，最终函数就会用相应位置的变量来替代那个说明符，产生一个调用者想要的字符串。<br><br><br>格式化数字字符串<br>sprintf&nbsp;最常见的应用之一莫过于把整数打印到字符串中，所以，spritnf&nbsp;在大多数场合可以替代<br>itoa。<br><br>如：<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把整数123&nbsp;打印成一个字符串保存在s&nbsp;中。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生"123"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">可以指定宽度，不足的左边补空格：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%8d%8d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4567</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："&nbsp;123&nbsp;4567"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">当然也可以左对齐：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%-8d%8d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">123</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4567</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："123&nbsp;4567"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">也可以按照16&nbsp;进制打印：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%8x</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4567</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">小写16&nbsp;进制，宽度占8&nbsp;个位置，右对齐</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%-8X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4568</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">大写16&nbsp;进制，宽度占8&nbsp;个位置，左对齐</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>这样，一个整数的16&nbsp;进制字符串就很容易得到，但我们在打印16&nbsp;进制内容时，通常想要一种左边补0&nbsp;的等宽格式，那该怎么做呢？很简单，在表示宽度的数字前面加个0&nbsp;就可以了。<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%08X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4567</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："000011D7"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">上面以&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">d&#8221;进行的10&nbsp;进制打印同样也可以使用这种左边补0&nbsp;的方式。<br><br><br>这里要注意一个符号扩展的问题：比如，假如我们想打印短整数（</span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">）</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;的内存16&nbsp;进制表示形式，在Win32&nbsp;平台上，一个short&nbsp;型占2&nbsp;个字节，所以我们自然希望用4&nbsp;个16&nbsp;进制数字来打印它：<br></span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">&nbsp;si&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%04X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;si);<br>产生&#8220;FFFFFFFF&#8221;，怎么回事？因为spritnf&nbsp;是个变参函数，除了前面两个参数之外，后面的参数都不是类型安全的，函数更没有办法仅仅通过一个&#8220;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">X&#8221;就能得知当初函数调用前参数压栈时被压进来的到底是个4&nbsp;字节的整数还是个2&nbsp;字节的短整数，所以采取了统一4&nbsp;字节的处理方式，导致参数压栈时做了符号扩展，扩展成了32&nbsp;位的整数</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">，打印时4&nbsp;个位置不够了，就把32&nbsp;位整数</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;的8&nbsp;位16&nbsp;进制都打印出来了。<br><br>如果你想看si&nbsp;的本来面目，那么就应该让编译器做0&nbsp;扩展而不是符号扩展（扩展时二进制左边补0&nbsp;而不是补符号位）：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%04X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;(unsigned&nbsp;</span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">)si);<br>就可以了。或者：<br>unsigned&nbsp;</span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">&nbsp;si&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%04X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;si);<br><br><br>sprintf&nbsp;和printf&nbsp;还可以按8&nbsp;进制打印整数字符串，使用&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">o&#8221;。注意8&nbsp;进制和16&nbsp;进制都不会打<br>印出负数，都是无符号的，实际上也就是变量的内部编码的直接的16&nbsp;进制或8&nbsp;进制表示。<br><br><br>控制浮点数打印格式<br>浮点数的打印和格式控制是sprintf&nbsp;的又一大常用功能，浮点数使用格式符&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">f&#8221;控制，默认保<br>留小数点后6&nbsp;位数字，比如：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3.1415926</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生"3.141593"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">但有时我们希望自己控制打印的宽度和小数位数，这时就应该使用：&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">m.nf&#8221;格式，其中m&nbsp;表<br>示打印的宽度，n&nbsp;表示小数点后的位数。比如：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%10.3f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3.1415626</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："&nbsp;3.142"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%-10.3f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3.1415626</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："3.142&nbsp;"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.3f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3.1415626</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">不指定总宽度，产生："3.142"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br><br>注意一个问题，你猜<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">;<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.2f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;i);<br>会打出什么东东来？&#8220;</span><span style="COLOR: #000000">100.00</span><span style="COLOR: #000000">&#8221;？对吗？自己试试就知道了，同时也试试下面这个：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.2f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">)i);<br>第一个打出来的肯定不是正确结果，原因跟前面提到的一样，参数压栈时调用者并不知道跟i相对应的格式控制符是个&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">f&#8221;。而函数执行时函数本身则并不知道当年被压入栈里的是个整数，于是可怜的保存整数i&nbsp;的那4&nbsp;个字节就被不由分说地强行作为浮点数格式来解释了，整个乱套了。不过，如果有人有兴趣使用手工编码一个浮点数，那么倒可以使用这种方法来检验一下你手工编排的结果是否正确。<br><br><br>字符</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">Ascii&nbsp;码对照<br>我们知道，在C</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">语言中，</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;也是一种普通的scalable&nbsp;类型，除了字长之外，它与short，<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">，</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;这些类型没有本质区别，只不过被大家习惯用来表示字符和字符串而已。（或许当年该把<br>这个类型叫做&#8220;</span><span style="COLOR: #0000ff">byte</span><span style="COLOR: #000000">&#8221;，然后现在就可以根据实际情况，使用byte&nbsp;或short&nbsp;来把char&nbsp;通过typedef&nbsp;定义出来，这样更合适些）于是，使用&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">d&#8221;或者&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">x&#8221;打印一个字符，便能得出它的10&nbsp;进制或16&nbsp;进制的ASCII&nbsp;码；反过来，使用&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">c&#8221;打印一个整数，便可以看到它所对应的ASCII&nbsp;字符。以下程序段把所有可见字符的ASCII&nbsp;码对照表打印到屏幕上（这里采用printf，注意&#8221;#&#8221;与&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">X&#8221;合用时自动为16&nbsp;进制数增加&#8221;0X&#8221;前缀）：<br></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">127</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)&nbsp;{<br>printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">[&nbsp;%c&nbsp;]:&nbsp;%3d&nbsp;0x%#04X\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;i,&nbsp;i,&nbsp;i);<br>}<br><br><br>连接字符串<br>sprintf&nbsp;的格式控制串中既然可以插入各种东西，并最终把它们&#8220;连成一串&#8221;，自然也就能够连<br>接字符串，从而在许多场合可以替代strcat，但sprintf&nbsp;能够一次连接多个字符串（自然也可以同时<br>在它们中间插入别的内容，总之非常灵活）。比如：<br></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;who&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">I</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;whom&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">CSDN</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s&nbsp;love&nbsp;%s.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;who,&nbsp;whom);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："I&nbsp;love&nbsp;CSDN.&nbsp;"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">strcat&nbsp;只能连接字符串（一段以&#8217;&#8217;结尾的字符数组或叫做字符缓冲，</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">terminated</span><span style="COLOR: #000000">-</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">），但有时我们有两段字符缓冲区，他们并不是以&nbsp;&#8217;&#8217;结尾。比如许多从第三方库函数中返回的字符数组，从硬件或者网络传输中读进来的字符流，它们未必每一段字符序列后面都有个相应的&#8217;&#8217;来结尾。如果直接连接，不管是sprintf&nbsp;还是strcat&nbsp;肯定会导致非法内存操作，而strncat&nbsp;也至少要求第一个参数是个null</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">terminated</span><span style="COLOR: #000000">-</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">，那该怎么办呢？我们自然会想起前面介绍打印整数和浮点数时可以指定宽度，字符串也一样的。比如：<br></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;a1[]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">B</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">D</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">E</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">F</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">G</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">};<br></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;a2[]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">H</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">I</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">J</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">K</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">L</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">M</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">N</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">};<br>如果：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s%s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;a1,&nbsp;a2);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Don't&nbsp;do&nbsp;that!</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">十有八九要出问题了。是否可以改成：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%7s%7s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;a1,&nbsp;a2);<br>也没好到哪儿去，正确的应该是：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.7s%.7s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;a1,&nbsp;a2);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："ABCDEFGHIJKLMN"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">这可以类比打印浮点数的&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">m.nf&#8221;，在&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">m.ns&#8221;中，m&nbsp;表示占用宽度（字符串长度不足时补空格，超出了则按照实际宽度打印），n&nbsp;才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m&nbsp;没什么大用，还是点号后面的n&nbsp;用的多。自然，也可以前后都只取部分字符：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.6s%.5s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;a1,&nbsp;a2);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生："ABCDEFHIJKL"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">在许多时候，我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的，而不是静态指定的，因为许多时候，程序要到运行时才会清楚到底需要取字符数组中的几个字符，这种动态的宽度</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">精度设置功能在sprintf&nbsp;的实现中也被考虑到了，sprintf&nbsp;采用&#8221;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&#8221;来占用一个本来需要一个指定宽度或精度的常数数字的位置，同样，而实际的宽度或精度就可以和其它被打印的变量一样被提供出来，于是，上面的例子可以变成：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.*s%.*s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,&nbsp;a1,&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,&nbsp;a2);<br>或者：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.*s%.*s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(a1),&nbsp;a1,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(a2),&nbsp;a2);<br>实际上，前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值，比如：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%-*d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生"65&nbsp;"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%#0*X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">128</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生"0X000080"，"#"产生0X</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%*.*f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">3.1415926</span><span style="COLOR: #000000">);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生"&nbsp;3.14"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br><br>打印地址信息<br>有时调试程序时，我们可能想查看某些变量或者成员的地址，由于地址或者指针也不过是个32&nbsp;位的数，你完全可以使用打印无符号整数的&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">u&#8221;把他们打印出来：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%u</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">i);<br>不过通常人们还是喜欢使用16&nbsp;进制而不是10&nbsp;进制来显示一个地址：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%08X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">i);<br>然而，这些都是间接的方法，对于地址打印，sprintf&nbsp;提供了专门的&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">p&#8221;：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%p</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">i);<br>我觉得它实际上就相当于：<br>sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%0*x</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">i);<br>利用sprintf&nbsp;的返回值<br>较少有人注意printf</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">sprintf&nbsp;函数的返回值，但有时它却是有用的，spritnf&nbsp;返回了本次函数调用<br>最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf&nbsp;调用结束以后，你无须再调用一次<br>strlen&nbsp;便已经知道了结果字符串的长度。如：<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;len&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;sprintf(s,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;i);<br>对于正整数来说，len&nbsp;便等于整数i&nbsp;的10&nbsp;进制位数。<br>下面的是个完整的例子，产生10&nbsp;个[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">)之间的随机数，并将他们打印到一个字符数组s&nbsp;中，<br>以逗号分隔开。<br>#include&nbsp;<br>#include&nbsp;<br>#include&nbsp;<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp;srand(time(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">));<br></span><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp;char</span><span style="COLOR: #000000">&nbsp;s[</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">];<br></span><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp;int</span><span style="COLOR: #000000">&nbsp;offset&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp;for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;sprintf(s&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;offset,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;rand()&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;s[offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\n</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">将最后一个逗号换成换行符。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;printf(s);<br></span><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp;return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br>设想当你从数据库中取出一条记录，然后希望把他们的各个字段按照某种规则连接成一个字<br>符串时，就可以使用这种方法，从理论上讲，他应该比不断的strcat&nbsp;效率高，因为strcat&nbsp;每次调用<br>都需要先找到最后的那个&#8217;&#8217;的位置，而在上面给出的例子中，我们每次都利用sprintf&nbsp;返回值把这<br>个位置直接记下来了。<br><br><br>使用sprintf&nbsp;的常见问题<br>sprintf&nbsp;是个变参函数，使用时经常出问题，而且只要出问题通常就是能导致程序崩溃的内存访<br>问错误，但好在由sprintf&nbsp;误用导致的问题虽然严重，却很容易找出，无非就是那么几种情况，通<br>常用眼睛再把出错的代码多看几眼就看出来了。<br><br><br></span><span style="COLOR: #000000">??</span><span style="COLOR: #000000">&nbsp;缓冲区溢出<br>第一个参数的长度太短了，没的说，给个大点的地方吧。当然也可能是后面的参数的问<br>题，建议变参对应一定要细心，而打印字符串时，尽量使用&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">.ns&#8221;的形式指定最大字符数。<br><br><br></span><span style="COLOR: #000000">??</span><span style="COLOR: #000000">&nbsp;忘记了第一个参数<br>低级得不能再低级问题，用printf&nbsp;用得太惯了。</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">偶就常犯。：。（</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #000000">??</span><span style="COLOR: #000000">&nbsp;变参对应出问题<br>通常是忘记了提供对应某个格式符的变参，导致以后的参数统统错位，检查检查吧。尤<br>其是对应&#8221;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&#8221;的那些参数，都提供了吗？不要把一个整数对应一个&#8221;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">s&#8221;，编译器会觉得你<br>欺她太甚了（编译器是obj&nbsp;和exe&nbsp;的妈妈，应该是个女的，:P）。<br><br><br>strftime<br>sprnitf&nbsp;还有个不错的表妹：strftime，专门用于格式化时间字符串的，用法跟她表哥很像，也<br>是一大堆格式控制符，只是毕竟小姑娘家心细，她还要调用者指定缓冲区的最大长度，可能是为<br>了在出现问题时可以推卸责任吧。这里举个例子：<br>time_t&nbsp;t&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;time(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">产生"YYYY-MM-DD&nbsp;hh:mm:ss"格式的字符串。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;s[</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">];<br>strftime(s,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(s),&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%Y-%m-%d&nbsp;%H:%M:%S</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;localtime(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t));<br>sprintf&nbsp;在MFC&nbsp;中也能找到他的知音：CString::Format，strftime&nbsp;在MFC&nbsp;中自然也有她的同道：<br>CTime::Format，这一对由于从面向对象哪里得到了赞助，用以写出的代码更觉优雅。<br></span></div>
<img src ="http://www.cppblog.com/Hero/aggbug/58400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Hero/" target="_blank">Hero</a> 2008-08-09 19:23 <a href="http://www.cppblog.com/Hero/archive/2008/08/09/58400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>