﻿<?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++博客-网络服务器软件开发/中间件开发，关注ACE/TAO/ICE-随笔分类-C++基础</title><link>http://www.cppblog.com/true/category/3840.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Dec 2010 16:20:32 GMT</lastBuildDate><pubDate>Wed, 29 Dec 2010 16:20:32 GMT</pubDate><ttl>60</ttl><item><title>C++中使用C#的App.Config配置文件</title><link>http://www.cppblog.com/true/archive/2010/12/29/137630.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Tue, 28 Dec 2010 16:25:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2010/12/29/137630.html</guid><wfw:comment>http://www.cppblog.com/true/comments/137630.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2010/12/29/137630.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/137630.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/137630.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 自从做公司的SNS社区以来，写了不少的C#代码，与C++相比，C#是易于使用的，开发效率提高很多倍，其中印象比较深刻的是，在一个C#工程中，可以通过向导添加配置文件，默认文件名为App.Config,是XML格式，一般内容为：<br>
<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; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&lt;?</span><span style="COLOR: #000000">xml&nbsp;version</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">1.0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;encoding</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">utf-8</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">?&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">configuration</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">appSettings</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">add&nbsp;key</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Ip</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">localhost</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">add&nbsp;key</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Port</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">8888</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">add&nbsp;key</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ServiceName</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Indexer</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">appSettings</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">configuration</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
通过在appSettings里面添加add元素，即可实现通常的配置功能，更重要的是，可以进一步扩展为多级的树形结构，与Ini格式相比，更直观，可读性更强，下面是基于CMarkup（<a href="http://www.firstobject.com/">http://www.firstobject.com/</a>）的一个简单实现：<br>头文件如下：<br>
<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; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#pragma&nbsp;once<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">map</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;AppConfig<br><img id=Codehighlighter1_65_242_Open_Image onclick="this.style.display='none'; Codehighlighter1_65_242_Open_Text.style.display='none'; Codehighlighter1_65_242_Closed_Image.style.display='inline'; Codehighlighter1_65_242_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_65_242_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_242_Closed_Text.style.display='none'; Codehighlighter1_65_242_Open_Image.style.display='inline'; Codehighlighter1_65_242_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_65_242_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_65_242_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;AppConfig(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">AppConfig(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetInt(std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;key);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;GetString(std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;key);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;std::map</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">,std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;config_map_;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">extern</span><span style="COLOR: #000000">&nbsp;AppConfig&nbsp;appConfig;</span></div>
源文件如下：<br>
<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; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">AppConfig.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Markup.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>AppConfig&nbsp;appConfig;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>AppConfig::AppConfig(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_95_442_Open_Image onclick="this.style.display='none'; Codehighlighter1_95_442_Open_Text.style.display='none'; Codehighlighter1_95_442_Closed_Image.style.display='inline'; Codehighlighter1_95_442_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_95_442_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_95_442_Closed_Text.style.display='none'; Codehighlighter1_95_442_Open_Image.style.display='inline'; Codehighlighter1_95_442_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_95_442_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_95_442_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CMarkup&nbsp;parser;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">parser.Load(&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">App.Config</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;&nbsp;))<br><img id=Codehighlighter1_151_166_Open_Image onclick="this.style.display='none'; Codehighlighter1_151_166_Open_Text.style.display='none'; Codehighlighter1_151_166_Closed_Image.style.display='inline'; Codehighlighter1_151_166_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_151_166_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_151_166_Closed_Text.style.display='none'; Codehighlighter1_151_166_Open_Image.style.display='inline'; Codehighlighter1_151_166_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_151_166_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_151_166_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(parser.FindChildElem(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">appSettings</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">))<br><img id=Codehighlighter1_211_438_Open_Image onclick="this.style.display='none'; Codehighlighter1_211_438_Open_Text.style.display='none'; Codehighlighter1_211_438_Closed_Image.style.display='inline'; Codehighlighter1_211_438_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_211_438_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_211_438_Closed_Text.style.display='none'; Codehighlighter1_211_438_Open_Image.style.display='inline'; Codehighlighter1_211_438_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_211_438_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_211_438_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parser.IntoElem();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(parser.FindChildElem(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">add</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">))<br><img id=Codehighlighter1_274_413_Open_Image onclick="this.style.display='none'; Codehighlighter1_274_413_Open_Text.style.display='none'; Codehighlighter1_274_413_Closed_Image.style.display='inline'; Codehighlighter1_274_413_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_274_413_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_274_413_Closed_Text.style.display='none'; Codehighlighter1_274_413_Open_Image.style.display='inline'; Codehighlighter1_274_413_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_274_413_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_274_413_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;key&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;parser.GetChildAttrib(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">key</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;value&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;parser.GetChildAttrib(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;config_map_[key]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;value;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parser.OutOfElem();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>AppConfig::</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">AppConfig(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_473_475_Open_Image onclick="this.style.display='none'; Codehighlighter1_473_475_Open_Text.style.display='none'; Codehighlighter1_473_475_Closed_Image.style.display='inline'; Codehighlighter1_473_475_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_473_475_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_473_475_Closed_Text.style.display='none'; Codehighlighter1_473_475_Open_Image.style.display='inline'; Codehighlighter1_473_475_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_473_475_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_473_475_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;AppConfig::GetInt(&nbsp;std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;key&nbsp;)<br><img id=Codehighlighter1_519_641_Open_Image onclick="this.style.display='none'; Codehighlighter1_519_641_Open_Text.style.display='none'; Codehighlighter1_519_641_Closed_Image.style.display='inline'; Codehighlighter1_519_641_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_519_641_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_519_641_Closed_Text.style.display='none'; Codehighlighter1_519_641_Open_Image.style.display='inline'; Codehighlighter1_519_641_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_519_641_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_519_641_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(config_map_.find(key)&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;config_map_.end())<br><img id=Codehighlighter1_571_615_Open_Image onclick="this.style.display='none'; Codehighlighter1_571_615_Open_Text.style.display='none'; Codehighlighter1_571_615_Closed_Image.style.display='inline'; Codehighlighter1_571_615_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_571_615_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_571_615_Closed_Text.style.display='none'; Codehighlighter1_571_615_Open_Image.style.display='inline'; Codehighlighter1_571_615_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_571_615_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_571_615_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;atoi(config_map_[key].c_str());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_624_639_Open_Image onclick="this.style.display='none'; Codehighlighter1_624_639_Open_Text.style.display='none'; Codehighlighter1_624_639_Closed_Image.style.display='inline'; Codehighlighter1_624_639_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_624_639_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_624_639_Closed_Text.style.display='none'; Codehighlighter1_624_639_Open_Image.style.display='inline'; Codehighlighter1_624_639_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_624_639_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_624_639_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;AppConfig::GetString(&nbsp;std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;key&nbsp;)<br><img id=Codehighlighter1_696_805_Open_Image onclick="this.style.display='none'; Codehighlighter1_696_805_Open_Text.style.display='none'; Codehighlighter1_696_805_Closed_Image.style.display='inline'; Codehighlighter1_696_805_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_696_805_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_696_805_Closed_Text.style.display='none'; Codehighlighter1_696_805_Open_Image.style.display='inline'; Codehighlighter1_696_805_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_696_805_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_696_805_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(config_map_.find(key)&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;config_map_.end())<br><img id=Codehighlighter1_748_778_Open_Image onclick="this.style.display='none'; Codehighlighter1_748_778_Open_Text.style.display='none'; Codehighlighter1_748_778_Closed_Image.style.display='inline'; Codehighlighter1_748_778_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_748_778_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_748_778_Closed_Text.style.display='none'; Codehighlighter1_748_778_Open_Image.style.display='inline'; Codehighlighter1_748_778_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_748_778_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_748_778_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;config_map_[key];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_787_803_Open_Image onclick="this.style.display='none'; Codehighlighter1_787_803_Open_Text.style.display='none'; Codehighlighter1_787_803_Closed_Image.style.display='inline'; Codehighlighter1_787_803_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_787_803_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_787_803_Closed_Text.style.display='none'; Codehighlighter1_787_803_Open_Image.style.display='inline'; Codehighlighter1_787_803_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_787_803_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_787_803_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>测试代码为：<br>
<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; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;MarkupTest.cpp&nbsp;:&nbsp;定义控制台应用程序的入口点。<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">AppConfig.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_162_309_Open_Image onclick="this.style.display='none'; Codehighlighter1_162_309_Open_Text.style.display='none'; Codehighlighter1_162_309_Closed_Image.style.display='inline'; Codehighlighter1_162_309_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_162_309_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_162_309_Closed_Text.style.display='none'; Codehighlighter1_162_309_Open_Image.style.display='inline'; Codehighlighter1_162_309_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_162_309_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_162_309_Open_Text><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;appConfig.GetString(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Ip</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">-----</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;appConfig.GetInt(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Port</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">----</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;appConfig.GetString(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ServiceName</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<img src ="http://www.cppblog.com/true/aggbug/137630.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2010-12-29 00:25 <a href="http://www.cppblog.com/true/archive/2010/12/29/137630.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs2008调试后控制台窗口关不了[转帖]</title><link>http://www.cppblog.com/true/archive/2010/12/12/136225.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 12 Dec 2010 05:16:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2010/12/12/136225.html</guid><wfw:comment>http://www.cppblog.com/true/comments/136225.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2010/12/12/136225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/136225.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/136225.html</trackback:ping><description><![CDATA[<br>终于碰到这个问题了，原文链接：<a href="http://hi.baidu.com/zzy_cqok/blog/item/46ee33998777f3056f068c2b.html">http://hi.baidu.com/zzy_cqok/blog/item/46ee33998777f3056f068c2b.html</a><br><br>vs2008调试后控制台窗口关不了2010-07-29 16:19<br>最近用Visual Studio 2008 写一些控制台程序，调试后的时候，当走到完成的时候，这个控制台程序的窗口就关不了了。再调试的时候就会出现一个新的控制台程序。<br>在任务管理器还可以看到这个窗口，但是关不掉了。感觉这个控制台程序已经失控了。<br>虽然这个对电脑运行没有影响，但还是很不爽。而且最后关机还有问题，导致不能关机。<br>找到一些相关的网页也讨论的，最后结论是windows的一个更新KB978037导致cress.exe出了一些问题。<br>解决办法：删除KB978037更新，删除的办法是在控制面板的添加或删除程序面板里，勾选显示更新，找到KB978037更新，删除。<br>附别人的讨论记录：<a href="http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/e6d4a4f5-7002-401a-90e1-6174d7f9e3ca/">http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/e6d4a4f5-7002-401a-90e1-6174d7f9e3ca/</a><br>&nbsp;
<img src ="http://www.cppblog.com/true/aggbug/136225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2010-12-12 13:16 <a href="http://www.cppblog.com/true/archive/2010/12/12/136225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++实现的MD5算法</title><link>http://www.cppblog.com/true/archive/2010/09/04/125888.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sat, 04 Sep 2010 12:03:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2010/09/04/125888.html</guid><wfw:comment>http://www.cppblog.com/true/comments/125888.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2010/09/04/125888.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/125888.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/125888.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;首先说明这份代码的原创作者不是我，我只是做了一点简单的包装，在这里下载：<a href="http://www.cppblog.com/Files/true/md5lib.rar">http://www.cppblog.com/Files/true/md5lib.rar</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用说明：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（1）源代码主要提供了MD5类，在类之外提供了两个函数：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::string getMD5(std::ifstream&amp; stream);//这个是文件接口，计算文件内容的MD5<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::string getMD5(const char* str,unsigned int str_len);//这个就不用说了<br>想研究代码的话，参考MD5类的实现，如果只是用的话，只需会用上面的接口即可<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（2）std::string getMD5(const char* str,unsigned int str_len)的使用：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string sName = "MD5";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string sMD5&nbsp; = getMD5(sName.c_str(),sName.length());<br>此时sMD5的值为：7f138a09169b250e9dcb378140907378<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（3）std::string getMD5(std::ifstream&amp; stream)的使用：创建md5.txt，内容为：MD5<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ifstream file("md5.txt");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string sMD5File = getMD5(file);<br>sMD5File 的也是：7f138a09169b250e9dcb378140907378<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（4）linux下提供md5sum,将上面的md5.txt传到linux下，然后：md5sum md5.txt，结果和上面一样。注意，一定要确认md5.txt内容为3个字节，如果直接登录上linux，用vi创建md5.txt，然后输入&#8220;MD5&#8221;，最后保存，这种方式linux下会追加一个空行，导致MD5值不一致。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（5）安全意识要树立，这个网站<a href="http://www.cmd5.com/">http://www.cmd5.com/</a>以网页形式提供md5解密，将上面的7f138a09169b250e9dcb378140907378的输入，几秒时间，得到MD5
<img src ="http://www.cppblog.com/true/aggbug/125888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2010-09-04 20:03 <a href="http://www.cppblog.com/true/archive/2010/09/04/125888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++结构体序列化的一点思考</title><link>http://www.cppblog.com/true/archive/2009/09/24/97087.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Wed, 23 Sep 2009 19:03:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2009/09/24/97087.html</guid><wfw:comment>http://www.cppblog.com/true/comments/97087.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2009/09/24/97087.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/97087.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/97087.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++结构体序列化  libprotobuf&nbsp;&nbsp;<a href='http://www.cppblog.com/true/archive/2009/09/24/97087.html'>阅读全文</a><img src ="http://www.cppblog.com/true/aggbug/97087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2009-09-24 03:03 <a href="http://www.cppblog.com/true/archive/2009/09/24/97087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对基本类型的再包装，方便了移植</title><link>http://www.cppblog.com/true/archive/2009/02/02/72782.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Mon, 02 Feb 2009 02:51:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2009/02/02/72782.html</guid><wfw:comment>http://www.cppblog.com/true/comments/72782.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2009/02/02/72782.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/72782.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/72782.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 对基本类型的再包装&nbsp;&nbsp;<a href='http://www.cppblog.com/true/archive/2009/02/02/72782.html'>阅读全文</a><img src ="http://www.cppblog.com/true/aggbug/72782.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2009-02-02 10:51 <a href="http://www.cppblog.com/true/archive/2009/02/02/72782.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux下信号处理函数实现的一点理解</title><link>http://www.cppblog.com/true/archive/2009/01/15/72072.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Thu, 15 Jan 2009 03:39:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2009/01/15/72072.html</guid><wfw:comment>http://www.cppblog.com/true/comments/72072.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2009/01/15/72072.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/72072.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/72072.html</trackback:ping><description><![CDATA[<p>代码操作步骤如下：<br><br>[tqg@localhost test]$ vi test.cpp </p>
<p><br>#include &lt;pthread.h&gt;<br>#include &lt;signal.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;unistd.h&gt;</p>
<p>void signal_handler(int sig)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("catch signal: %d,thread id = %u\n",sig,pthread_self());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_exit(0);<br>}</p>
<p>void* thread_handler(void*arg)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signal(SIGQUIT,signal_handler);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("thread arg = %s\n",(char*)arg);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(10);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("in thread\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (void*)0;<br>} </p>
<p>int main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char* pArg = "hello";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_t tid;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_create(&amp;tid,NULL,thread_handler,pArg);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("main thread id = %u\n",pthread_self());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(2);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("killing now\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_kill(tid,SIGQUIT);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(20);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("exit main now\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br>~<br>~<br>~<br>~<br>"test.cpp" 42L, 648C written<br>[tqg@localhost test]$ g++ -o test test.cpp -lpthread<br>[tqg@localhost test]$ ./test <br>main thread id = 3086875296<br>thread arg = hello<br>killing now<br>catch signal: 3,thread id = 3086871472<br>exit main now<br>[tqg@localhost test]$ <br><br>可以看出，信号处理函数的执行是在要捕获信号的子线程thread_handler的上下文中执行的。</p>
<img src ="http://www.cppblog.com/true/aggbug/72072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2009-01-15 11:39 <a href="http://www.cppblog.com/true/archive/2009/01/15/72072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用GDB调试程序---转贴，非常全面的调试技巧</title><link>http://www.cppblog.com/true/archive/2009/01/11/71749.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 11 Jan 2009 12:21:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2009/01/11/71749.html</guid><wfw:comment>http://www.cppblog.com/true/comments/71749.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2009/01/11/71749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/71749.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/71749.html</trackback:ping><description><![CDATA[用GDB调试程序 <br>GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于，其可以形成执行序<br>列，形成脚本。UNIX下的软件全是命令行的，这给程序开发提代供了极大的便利，命令行<br>软件的优势在于，它们可以非常容易的集成在一起，使用几个简单的已有工具的命令，就可<br>以做出一个非常强大的功能。 <br>于是UNIX下的软件比Windows下的软件更能有机地结合，各自发挥各自的长处，组合成<br>更为强劲的功能。而Windows下的图形软件基本上是各自为营，互相不能调用，很不利于<br>各种软件的相互集成。在这里并不是要和Windows做个什么比较，所谓&#8220;寸有所长，尺有<br>所短&#8221;，图形化工具还是有不如命令行的地方。 <br>用GDB调试程序 <br>GDB概述 <br>———— <br>GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许，各位比较喜欢那<br>种图形界面方式的，像VC、BCB等IDE的调试，但如果你是在UNIX平台下做软件，你<br>会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓&#8220;寸有所长，<br>尺有所短&#8221;就是这个道理。 <br>一般来说，GDB主要帮忙你完成下面四个方面的功能： <br>1、启动你的程序，可以按照你的自定义的要求随心所欲的运行程序。 <br>2、可让被调试的程序在你所指定的调置的断点处停住。（断点可以是条件表达式） <br>3、当程序被停住时，可以检查此时你的程序中所发生的事。 <br>4、动态的改变你程序的执行环境。 <br>从上面看来，GDB和一般的调试工具没有什么两样，基本上也是完成这些功能，不过在细<br>节上，你会发现GDB这个调试工具的强大，大家可能比较习惯了图形化的调试工具，但有<br>时候，命令行的调试工具却有着图形化工具所不能完成的功能。让我们一一看来。 <br>一个调试示例 <br>—————— <br>源程序：tst.c <br>1 #include <br>2 <br>3 int func(int n) <br>4 { <br>5 int sum=0,i; <br>6 for(i=0; i&lt;7; i++) {
<p>8 sum+=i; <br>9 } <br>10 return sum; <br>11 } <br>12 <br>13 <br>14 main() <br>15 { <br>16 int i; <br>17 long result = 0; <br>18 for(i=1; i&lt;=100; i++) <br>19 { <br>20 result += i; <br>21 } <br>22 <br>23 printf("result[1-100] = %d \n", result ); <br>24 printf("result[1-250] = %d \n", func(250) ); <br>25 } <br>编译生成执行文件：（Linux下） <br>hchen/test&gt; cc -g tst.c -o tst <br>使用GDB调试： <br>hchen/test&gt; gdb tst &lt;---------- 启动GDB <br>GNU gdb 5.1.1 <br>Copyright 2002 Free Software Foundation, Inc. <br>GDB is free software, covered by the GNU General Public License, and you are <br>welcome to change it and/or distribute copies of it under certain conditions. <br>Type "show copying" to see the conditions. <br>There is absolutely no warranty for GDB. Type "show warranty" for details. <br>This GDB was configured as "i386-suse-linux"... <br>(gdb) l &lt;-------------------- l命令相当于list，从第一行开始例出原码。 <br>1 #include <br>2 <br>3 int func(int n) <br>4 { <br>5 int sum=0,i; <br>6 for(i=0; i 7 { <br>8 sum+=i; <br>9 } <br>10 return sum; <br>(gdb) &lt;-------------------- 直接回车表示，重复上一次命令 <br>11 } </p>
<p>12 <br>13 <br>14 main() <br>15 { <br>16 int i; <br>17 long result = 0; <br>18 for(i=1; i&lt;=100; i++) <br>19 { <br>20 result += i; <br>(gdb) break 16 &lt;-------------------- 设置断点，在源程序第16行处。 <br>Breakpoint 1 at 0x8048496: file tst.c, line 16. <br>(gdb) break func &lt;-------------------- 设置断点，在函数func()入口处。 <br>Breakpoint 2 at 0x8048456: file tst.c, line 5. <br>(gdb) info break &lt;-------------------- 查看断点信息。 <br>Num Type Disp Enb Address What <br>1 breakpoint keep y 0x08048496 in main at tst.c:16 <br>2 breakpoint keep y 0x08048456 in func at tst.c:5 <br>(gdb) r &lt;--------------------- 运行程序，run命令简写 <br>Starting program: /home/hchen/test/tst <br>Breakpoint 1, main () at tst.c:17 &lt;---------- 在断点处停住。 <br>17 long result = 0; <br>(gdb) n &lt;--------------------- 单条语句执行，next命令简写。 <br>18 for(i=1; i&lt;=100; i++) <br>(gdb) n <br>20 result += i; <br>(gdb) n <br>18 for(i=1; i&lt;=100; i++) <br>(gdb) n <br>20 result += i; <br>(gdb) c &lt;--------------------- 继续运行程序，continue命令简写。 <br>Continuing. <br>result[1-100] = 5050 &lt;----------程序输出。 <br>Breakpoint 2, func (n=250) at tst.c:5 <br>5 int sum=0,i; <br>(gdb) n <br>6 for(i=1; i&lt;=n; i++) <br>(gdb) p i &lt;--------------------- 打印变量i的值，print命令简写。 <br>$1 = 134513808 <br>(gdb) n <br>8 sum+=i; <br>(gdb) n <br>6 for(i=1; i&lt;=n; i++) </p>
<p>(gdb) p sum <br>$2 = 1 <br>(gdb) n <br>8 sum+=i; <br>(gdb) p i <br>$3 = 2 <br>(gdb) n <br>6 for(i=1; i&lt;=n; i++) <br>(gdb) p sum <br>$4 = 3 <br>(gdb) bt &lt;--------------------- 查看函数堆栈。 <br>#0 func (n=250) at tst.c:5 <br>#1 0x080484e4 in main () at tst.c:24 <br>#2 0x400409ed in __libc_start_main () from /lib/libc.so.6 <br>(gdb) finish &lt;--------------------- 退出函数。 <br>Run till exit from #0 func (n=250) at tst.c:5 <br>0x080484e4 in main () at tst.c:24 <br>24 printf("result[1-250] = %d \n", func(250) ); <br>Value returned is $6 = 31375 <br>(gdb) c &lt;--------------------- 继续运行。 <br>Continuing. <br>result[1-250] = 31375 &lt;----------程序输出。 <br>Program exited with code 027. &lt;--------程序退出，调试结束。 <br>(gdb) q &lt;--------------------- 退出gdb。 <br>hchen/test&gt; <br>好了，有了以上的感性认识，还是让我们来系统地认识一下gdb吧。 <br>使用GDB <br>———— <br>一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序，首先在编译时，我们必<br>须要把调试信息加到可执行文件中。使用编译器（cc/gcc/g++）的 -g 参数可以做到这一点。<br>如： <br>&gt; cc -g hello.c -o hello <br>&gt; g++ -g hello.cpp -o hello <br>如果没有-g，你将看不见程序的函数名、变量名，所代替的全是运行时的内存地址。当你用<br>-g把调试信息加入之后，并成功编译目标代码以后，让我们来看看如何用gdb来调试他。 <br>启动GDB的方法有以下几种： </p>
<p>1、gdb <br>program也就是你的执行文件，一般在当然目录下。 <br>2、gdb core <br>用gdb同时调试一个运行程序和core文件，core是程序非法执行后core dump后产生的文件。 <br>3、gdb <br>如果你的程序是一个服务程序，那么你可以指定这个服务程序运行时的进程ID。gdb会自<br>动attach上去，并调试他。program应该在PATH环境变量中搜索得到。 <br>GDB启动时，可以加上一些GDB的启动开关，详细的开关可以用gdb -help查看。我在下<br>面只例举一些比较常用的参数： <br>-symbols <br>-s <br>从指定文件中读取符号表。 <br>-se file <br>从指定文件中读取符号表信息，并把他用在可执行文件中。 <br>-core <br>-c <br>调试时core dump的core文件。 <br>-directory <br>-d <br>加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。 <br>GDB的命令概貌 <br>——————— <br>启动gdb后，就你被带入gdb的调试环境中，就可以使用gdb的命令开始调试程序了，gdb<br>的命令可以使用help命令来查看，如下所示： <br>/home/hchen&gt; gdb <br>GNU gdb 5.1.1 <br>Copyright 2002 Free Software Foundation, Inc. <br>GDB is free software, covered by the GNU General Public License, and you are <br>welcome to change it and/or distribute copies of it under certain conditions. <br>Type "show copying" to see the conditions. <br>There is absolutely no warranty for GDB. Type "show warranty" for details. <br>This GDB was configured as "i386-suse-linux". <br>(gdb) help </p>
<p>List of classes of commands: <br>aliases -- Aliases of other commands <br>breakpoints -- Making program stop at certain points <br>data -- Examining data <br>files -- Specifying and examining files <br>internals -- Maintenance commands <br>obscure -- Obscure features <br>running -- Running the program <br>stack -- Examining the stack <br>status -- Status inquiries <br>support -- Support facilities <br>tracepoints -- Tracing of program execution without stopping the program <br>user-defined -- User-defined commands <br>Type "help" followed by a class name for a list of commands in that class. <br>Type "help" followed by command name for full documentation. <br>Command name abbreviations are allowed if unambiguous. <br>(gdb) <br>gdb的命令很多，gdb把之分成许多个种类。help命令只是例出gdb的命令种类，如果要看<br>种类中的命令，可以使用help 命令，如：help breakpoints，查看设置断点的所有命令。也<br>可以直接help 来查看命令的帮助。 <br>gdb中，输入命令时，可以不用打全命令，只用打命令的前几个字符就可以了，当然，命令<br>的前几个字符应该要标志着一个唯一的命令，在Linux下，你可以敲击两次TAB键来补齐<br>命令的全称，如果有重复的，那么gdb会把其例出来。 <br>示例一：在进入函数func时，设置一个断点。可以敲入break func，或是直接就是b func <br>(gdb) b func <br>Breakpoint 1 at 0x8048458: file hello.c, line 10. <br>示例二：敲入b按两次TAB键，你会看到所有b打头的命令： <br>(gdb) b <br>backtrace break bt <br>(gdb) <br>示例三：只记得函数的前缀，可以这样： <br>(gdb) b make_ &lt;按TAB键&gt; <br>（再按下一次TAB键，你会看到:） <br>make_a_section_from_file make_environ <br>make_abs_section make_function_type <br>make_blockvector make_pointer_type </p>
<p>make_cleanup make_reference_type <br>make_command make_symbol_completion_list <br>(gdb) b make_ <br>GDB把所有make开头的函数全部例出来给你查看。 <br>示例四：调试C++的程序时，有可以函数名一样。如： <br>(gdb) b 'bubble( M-? <br>bubble(double,double) bubble(int,int) <br>(gdb) b 'bubble( <br>你可以查看到C++中的所有的重载函数及参数。（注：M-?和&#8220;按两次TAB键&#8221;是一个意思） <br>要退出gdb时，只用发quit或命令简称q就行了。 <br>GDB中运行UNIX的shell程序 <br>———————————— <br>在gdb环境中，你可以执行UNIX的shell的命令，使用gdb的shell命令来完成： <br>shell <br>调用UNIX的shell来执行，环境变量SHELL中定义的UNIX的shell将会被用来执行，如<br>果SHELL没有定义，那就使用UNIX的标准shell：/bin/sh。（在Windows中使用Command.com<br>或cmd.exe） <br>还有一个gdb命令是make： <br>make <br>可以在gdb中执行make命令来重新build自己的程序。这个命令等价于&#8220;shell make &#8221;。 <br>在GDB中运行程序 <br>———————— <br>当以gdb 方式启动gdb后，gdb会在PATH路径和当前目录中搜索的源文件。如要确认gdb<br>是否读到源文件，可使用l或list命令，看看gdb是否能列出源代码。 <br>在gdb中，运行程序使用r或是run命令。程序的运行，你有可能需要设置下面四方面的事。 <br>1、程序运行参数。 <br>set args 可指定运行时参数。（如：set args 10 20 30 40 50） <br>show args 命令可以查看设置好的运行参数。 <br>2、运行环境。 <br>path <br>可设定程序的运行路径。 <br>show paths 查看程序的运行路径。 </p>
<p>set environment varname [=value] 设置环境变量。如：set env USER=hchen <br>show environment [varname] 查看环境变量。 <br>3、工作目录。 <br>cd <br>相当于shell的cd命令。 <br>pwd 显示当前的所在目录。 <br>4、程序的输入输出。 <br>info terminal 显示你程序用到的终端的模式。 <br>使用重定向控制程序输出。如：run &gt; outfile <br>tty命令可以指写输入输出的终端设备。如：tty /dev/ttyb <br>调试已运行的程序 <br>———————— <br>两种方法： <br>1、在UNIX下用ps查看正在运行的程序的PID（进程ID），然后用gdb PID格式挂接正在<br>运行的程序。 <br>2、先用gdb 关联上源代码，并进行gdb，在gdb中用attach命令来挂接进程的PID。并用<br>detach来取消挂接的进程。 <br>暂停 / 恢复程序运行 <br>————————— <br>调试程序中，暂停程序运行是必须的，GDB可以方便地暂停程序的运行。你可以设置程序<br>的在哪行停住，在什么条件下停住，在收到什么信号时停往等等。以便于你查看运行时的变<br>量，以及运行时的流程。 <br>当进程被gdb停住时，你可以使用info program 来查看程序的是否在运行，进程号，被暂停<br>的原因。 <br>在gdb中，我们可以有以下几种暂停方式：断点（BreakPoint）、观察点（WatchPoint）、捕<br>捉点（CatchPoint）、信号（Signals）、线程停止（Thread Stops）。如果要恢复程序运行，可<br>以使用c或是continue命令。 <br>一、设置断点（BreakPoint） <br>我们用break命令来设置断点。正面有几点设置断点的方法： <br>break <br>在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函</p>
<p>数名。 <br>break <br>在指定行号停住。 <br>break +offset <br>break -offset <br>在当前行号的前面或后面的offset行停住。offiset为自然数。 <br>break filename:linenum <br>在源文件filename的linenum行处停住。 <br>break filename:function <br>在源文件filename的function函数的入口处停住。 <br>break *address <br>在程序运行的内存地址处停住。 <br>break <br>break命令没有参数时，表示在下一条指令处停住。 <br>break ... if <br>...可以是上述的参数，condition表示条件，在条件成立时停住。比如在循环境体中，可以设<br>置break if i=100，表示当i为100时停住程序。 <br>查看断点时，可使用info命令，如下所示：（注：n表示断点号） <br>info breakpoints [n] <br>info break [n] <br>二、设置观察点（WatchPoint） <br>观察点一般来观察某个表达式（变量也是一种表达式）的值是否有变化了，如果有变化，马<br>上停住程序。我们有下面的几种方法来设置观察点： <br>watch <br>为表达式（变量）expr设置一个观察点。一量表达式值有变化时，马上停住程序。 <br>rwatch <br>当表达式（变量）expr被读时，停住程序。 <br>awatch <br>当表达式（变量）的值被读或被写时，停住程序。 </p>
<p>info watchpoints <br>列出当前所设置了的所有观察点。 <br>三、设置捕捉点（CatchPoint） <br>你可设置捕捉点来补捉程序运行时的一些事件。如：载入共享库（动态链接库）或是C++<br>的异常。设置捕捉点的格式为： <br>catch <br>当event发生时，停住程序。event可以是下面的内容： <br>1、throw 一个C++抛出的异常。（throw为关键字） <br>2、catch 一个C++捕捉到的异常。（catch为关键字） <br>3、exec 调用系统调用exec时。（exec为关键字，目前此功能只在HP-UX下有用） <br>4、fork 调用系统调用fork时。（fork为关键字，目前此功能只在HP-UX下有用） <br>5、vfork 调用系统调用vfork时。（vfork为关键字，目前此功能只在HP-UX下有用） <br>6、load 或 load 载入共享库（动态链接库）时。（load为关键字，目前此功能只在HP-UX<br>下有用） <br>7、unload 或 unload 卸载共享库（动态链接库）时。（unload为关键字，目前此功能只在<br>HP-UX下有用） <br>tcatch <br>只设置一次捕捉点，当程序停住以后，应点被自动删除。 <br>四、维护停止点 <br>上面说了如何设置程序的停止点，GDB中的停止点也就是上述的三类。在GDB中，如果你<br>觉得已定义好的停止点没有用了，你可以使用delete、clear、disable、enable这几个命令来<br>进行维护。 <br>clear <br>清除所有的已定义的停止点。 <br>clear <br>clear <br>清除所有设置在函数上的停止点。 <br>clear <br>clear <br>清除所有设置在指定行上的停止点。 <br>delete [breakpoints] [range...] <br>删除指定的断点，breakpoints为断点号。如果不指定断点号，则表示删除所有的断点。range <br>表示断点号的范围（如：3-7）。其简写命令为d。 </p>
<p>比删除更好的一种方法是disable停止点，disable了的停止点，GDB不会删除，当你还需要<br>时，enable即可，就好像回收站一样。 <br>disable [breakpoints] [range...] <br>disable所指定的停止点，breakpoints为停止点号。如果什么都不指定，表示disable所有的<br>停止点。简写命令是dis. <br>enable [breakpoints] [range...] <br>enable所指定的停止点，breakpoints为停止点号。 <br>enable [breakpoints] once range... <br>enable所指定的停止点一次，当程序停止后，该停止点马上被GDB自动disable。 <br>enable [breakpoints] delete range... <br>enable所指定的停止点一次，当程序停止后，该停止点马上被GDB自动删除。 <br>五、停止条件维护 <br>前面在说到设置断点时，我们提到过可以设置一个条件，当条件成立时，程序自动停止，这<br>是一个非常强大的功能，这里，我想专门说说这个条件的相关维护命令。一般来说，为断点<br>设置一个条件，我们使用if关键词，后面跟其断点条件。并且，条件设置好后，我们可以<br>用condition命令来修改断点的条件。（只有break和watch命令支持if，catch目前暂不支持<br>if） <br>condition <br>修改断点号为bnum的停止条件为expression。 <br>condition <br>清除断点号为bnum的停止条件。 <br>还有一个比较特殊的维护命令ignore，你可以指定程序运行时，忽略停止条件几次。 <br>ignore <br>表示忽略断点号为bnum的停止条件count次。 <br>六、为停止点设定运行命令 <br>我们可以使用GDB提供的command命令来设置停止点的运行命令。也就是说，当运行的<br>程序在被停止住时，我们可以让其自动运行一些别的命令，这很有利行自动化调试。对基于<br>GDB的自动化调试是一个强大的支持。 <br>commands [bnum] </p>
<p>... command-list ... <br>end <br>为断点号bnum指写一个命令列表。当程序被该断点停住时，gdb会依次运行命令列表中的<br>命令。 <br>例如： <br>break foo if x&gt;0 <br>commands <br>printf "x is %d\n",x <br>continue <br>end <br>断点设置在函数foo中，断点条件是x&gt;0，如果程序被断住后，也就是，一旦x的值在foo<br>函数中大于0，GDB会自动打印出x的值，并继续运行程序。 <br>如果你要清除断点上的命令序列，那么只要简单的执行一下commands命令，并直接在打个<br>end就行了。 <br>七、断点菜单 <br>在C++中，可能会重复出现同一个名字的函数若干次（函数重载），在这种情况下，break 不<br>能告诉GDB要停在哪个函数的入口。当然，你可以使用break 也就是把函数的参数类型告<br>诉GDB，以指定一个函数。否则的话，GDB会给你列出一个断点菜单供你选择你所需要的<br>断点。你只要输入你菜单列表中的编号就可以了。如： <br>(gdb) b String::after <br>[0] cancel <br>[1] all <br>[2] file:String.cc; line number:867 <br>[3] file:String.cc; line number:860 <br>[4] file:String.cc; line number:875 <br>[5] file:String.cc; line number:853 <br>[6] file:String.cc; line number:846 <br>[7] file:String.cc; line number:735 <br>&gt; 2 4 6 <br>Breakpoint 1 at 0xb26c: file String.cc, line 867. <br>Breakpoint 2 at 0xb344: file String.cc, line 875. <br>Breakpoint 3 at 0xafcc: file String.cc, line 846. <br>Multiple breakpoints were set. <br>Use the "delete" command to delete unwanted <br>breakpoints. <br>(gdb) </p>
<p>可见，GDB列出了所有after的重载函数，你可以选一下列表编号就行了。0表示放弃设置<br>断点，1表示所有函数都设置断点。 <br>八、恢复程序运行和单步调试 <br>当程序被停住了，你可以用continue命令恢复程序的运行直到程序结束，或下一个断点到来。<br>也可以使用step或next命令单步跟踪程序。 <br>continue [ignore-count] <br>c [ignore-count] <br>fg [ignore-count] <br>恢复程序运行，直到程序结束，或是下一个断点到来。ignore-count表示忽略其后的断点次<br>数。continue，c，fg三个命令都是一样的意思。 <br>step <br>单步跟踪，如果有函数调用，他会进入该函数。进入函数的前提是，此函数被编译有debug<br>信息。很像VC等工具中的step in。后面可以加count也可以不加，不加表示一条条地执行，<br>加表示执行后面的count条指令，然后再停住。 <br>next <br>同样单步跟踪，如果有函数调用，他不会进入该函数。很像VC等工具中的step over。后面<br>可以加count也可以不加，不加表示一条条地执行，加表示执行后面的count条指令，然后<br>再停住。 <br>set step-mode <br>set step-mode on <br>打开step-mode模式，于是，在进行单步跟踪时，程序不会因为没有debug信息而不停住。<br>这个参数有很利于查看机器码。 <br>set step-mod off <br>关闭step-mode模式。 <br>finish <br>运行程序，直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。 <br>until 或 u <br>当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 <br>stepi 或 si <br>nexti 或 ni <br>单步跟踪一条机器指令！一条程序代码有可能由数条机器指令完成，stepi和nexti可以单步<br>执行机器指令。与之一样有相同功能的命令是&#8220;display/i $pc&#8221; ，当运行完这个命令后，单<br>步跟踪会在打出程序代码的同时打出机器指令（也就是汇编代码） </p>
<p>九、信号（Signals） <br>信号是一种软中断，是一种处理异步事件的方法。一般来说，操作系统都支持许多信号。尤<br>其是UNIX，比较重要应用程序一般都会处理信号。UNIX定义了许多信号，比如SIGINT<br>表示中断字符信号，也就是Ctrl+C的信号，SIGBUS表示硬件故障的信号；SIGCHLD表示<br>子进程状态改变信号；SIGKILL表示终止程序运行的信号，等等。信号量编程是UNIX下<br>非常重要的一种技术。 <br>GDB有能力在你调试程序的时候处理任何一种信号，你可以告诉GDB需要处理哪一种信<br>号。你可以要求GDB收到你所指定的信号时，马上停住正在运行的程序，以供你进行调试。<br>你可以用GDB的handle命令来完成这一功能。 <br>handle <br>在GDB中定义一个信号处理。信号可以以SIG开头或不以SIG开头，可以用定义一个要处<br>理信号的范围（如：SIGIO-SIGKILL，表示处理从SIGIO信号到SIGKILL的信号，其中包<br>括SIGIO，SIGIOT，SIGKILL三个信号），也可以使用关键字all来标明要处理所有的信号。<br>一旦被调试的程序接收到信号，运行程序马上会被GDB停住，以供调试。其可以是以下几<br>种关键字的一个或多个。 <br>nostop <br>当被调试的程序收到信号时，GDB不会停住程序的运行，但会打出消息告诉你收到这种信<br>号。 <br>stop <br>当被调试的程序收到信号时，GDB会停住你的程序。 <br>print <br>当被调试的程序收到信号时，GDB会显示出一条信息。 <br>noprint <br>当被调试的程序收到信号时，GDB不会告诉你收到信号的信息。 <br>pass <br>noignore <br>当被调试的程序收到信号时，GDB不处理信号。这表示，GDB会把这个信号交给被调试程<br>序会处理。 <br>nopass <br>ignore <br>当被调试的程序收到信号时，GDB不会让被调试程序来处理这个信号。 <br>info signals <br>info handle <br>查看有哪些信号在被GDB检测中。 <br>十、线程（Thread Stops） </p>
<p>如果你程序是多线程的话，你可以定义你的断点是否在所有的线程上，或是在某个特定的线<br>程。GDB很容易帮你完成这一工作。 <br>break thread <br>break thread if ... <br>linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID，注意，这个ID是<br>GDB分配的，你可以通过&#8220;info threads&#8221;命令来查看正在运行程序中的线程信息。如果你<br>不指定thread 则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如： <br>(gdb) break frik.c:13 thread 28 if bartab &gt; lim <br>当你的程序被GDB停住时，所有的运行线程都会被停住。这方便你你查看运行程序的总体<br>情况。而在你恢复程序运行时，所有的线程也会被恢复运行。那怕是主进程在被单步调试时。 <br>查看栈信息 <br>————— <br>当程序被停住了，你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一<br>个函数，函数的地址，函数参数，函数内的局部变量都会被压入&#8220;栈&#8221;（Stack）中。你可以<br>用GDB命令来查看当前的栈中的信息。 <br>下面是一些查看函数调用栈信息的GDB命令： <br>backtrace <br>bt <br>打印当前的函数调用栈的所有信息。如： <br>(gdb) bt <br>#0 func (n=250) at tst.c:6 <br>#1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30 <br>#2 0x400409ed in __libc_start_main () from /lib/libc.so.6 <br>从上可以看出函数的调用栈信息：__libc_start_main --&gt; main() --&gt; func() <br>backtrace <br>bt <br>n是一个正整数，表示只打印栈顶上n层的栈信息。 <br>backtrace &lt;-n&gt; <br>bt &lt;-n&gt; <br>-n表一个负整数，表示只打印栈底下n层的栈信息。 <br>如果你要查看某一层的信息，你需要在切换当前的栈，一般来说，程序停止时，最顶层的栈</p>
<p>就是当前栈，如果你要查看栈下面层的详细信息，首先要做的是切换当前栈。 <br>frame <br>f <br>n是一个从0开始的整数，是栈中的层编号。比如：frame 0，表示栈顶，frame 1，表示栈的<br>第二层。 <br>up <br>表示向栈的上面移动n层，可以不打n，表示向上移动一层。 <br>down <br>表示向栈的下面移动n层，可以不打n，表示向下移动一层。 <br>上面的命令，都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三<br>个命令： <br>select-frame 对应于 frame 命令。 <br>up-silently 对应于 up 命令。 <br>down-silently 对应于 down 命令。 <br>查看当前栈层的信息，你可以用以下GDB命令： <br>frame 或 f <br>会打印出这些信息：栈的层编号，当前的函数名，函数参数值，函数所在文件及行号，函数<br>执行到的语句。 <br>info frame <br>info f <br>这个命令会打印出更为详细的当前栈层的信息，只不过，大多数都是运行时的内内地址。比<br>如：函数地址，调用函数的地址，被调用函数的地址，目前的函数是由什么样的程序语言写<br>成的、函数参数地址及值、局部变量的地址等等。如： <br>(gdb) info f <br>Stack level 0, frame at 0xbffff5d4: <br>eip = 0x804845d in func (tst.c:6); saved eip 0x8048524 <br>called by frame at 0xbffff60c <br>source language c. <br>Arglist at 0xbffff5d4, args: n=250 <br>Locals at 0xbffff5d4, Previous frame's sp is 0x0 <br>Saved registers: <br>ebp at 0xbffff5d4, eip at 0xbffff5d8 <br>info args </p>
<p>打印出当前函数的参数名及其值。 <br>info locals <br>打印出当前函数中所有局部变量及其值。 <br>info catch <br>打印出当前的函数中的异常处理信息。 <br>查看源程序 <br>————— <br>一、显示源代码 <br>GDB 可以打印出所调试程序的源代码，当然，在程序编译时一定要加上-g的参数，把源程<br>序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后，GDB会报告程序<br>停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。还是来看一看查看源<br>代码的GDB命令吧。 <br>list <br>显示程序第linenum行的周围的源程序。 <br>list <br>显示函数名为function的函数的源程序。 <br>list <br>显示当前行后面的源程序。 <br>list - <br>显示当前行前面的源程序。 <br>一般是打印当前行的上5行和下5行，如果显示函数是是上2行下8行，默认是10行，当<br>然，你也可以定制显示的范围，使用下面命令可以设置一次显示源程序的行数。 <br>set listsize <br>设置一次显示源代码的行数。 <br>show listsize <br>查看当前listsize的设置。 <br>list命令还有下面的用法： <br>list , </p>
<p>显示从first行到last行之间的源代码。 <br>list , <br>显示从当前行到last行之间的源代码。 <br>list + <br>往后显示源代码。 <br>一般来说在list后面可以跟以下这们的参数： <br>行号。 <br>&lt;+offset&gt; 当前行号的正偏移量。 <br>&lt;-offset&gt; 当前行号的负偏移量。 <br>哪个文件的哪一行。 <br>函数名。 <br>哪个文件中的哪个函数。 <br>&lt;*address&gt; 程序运行时的语句在内存中的地址。 <br>二、搜索源代码 <br>不仅如此，GDB还提供了源代码搜索的命令： <br>forward-search <br>search <br>向前面搜索。 <br>reverse-search <br>全部搜索。 <br>其中，就是正则表达式，也主一个字符串的匹配模式，关于正则表达式，我就不在这里讲了，<br>还请各位查看相关资料。 <br>三、指定源文件的路径 <br>某些时候，用-g编译过后的执行程序中只是包括了源文件的名字，没有路径名。GDB提供<br>了可以让你指定源文件的路径的命令，以便GDB进行搜索。 <br>directory <br>dir <br>加一个源文件路径到当前路径的前面。如果你要指定多个路径，UNIX下你可以使用&#8220;:&#8221;，<br>Windows下你可以使用&#8220;;&#8221;。 </p>
<p>directory <br>清除所有的自定义的源文件搜索路径信息。 <br>show directories <br>显示定义了的源文件搜索路径。 <br>四、源代码的内存 <br>你可以使用info line命令来查看源代码在内存中的地址。info line后面可以跟&#8220;行号&#8221;，&#8220;函<br>数名&#8221;，&#8220;文件名:行号&#8221;，&#8220;文件名:函数名&#8221;，这个命令会打印出所指定的源码在运行时的内<br>存地址，如： <br>(gdb) info line tst.c:func <br>Line 5 of "tst.c" starts at address 0x8048456 and ends at 0x804845d . <br>还有一个命令（disassemble）你可以查看源程序的当前执行时的机器码，这个命令会把目前<br>内存中的指令dump出来。如下面的示例表示查看函数func的汇编代码。 <br>(gdb) disassemble func <br>Dump of assembler code for function func: <br>0x8048450 : push %ebp <br>0x8048451 : mov %esp,%ebp <br>0x8048453 : sub $0x18,%esp <br>0x8048456 : movl $0x0,0xfffffffc(%ebp) <br>0x804845d : movl $0x1,0xfffffff8(%ebp) <br>0x8048464 : mov 0xfffffff8(%ebp),%eax <br>0x8048467 : cmp 0x8(%ebp),%eax <br>0x804846a : jle 0x8048470 <br>0x804846c : jmp 0x8048480 <br>0x804846e : mov %esi,%esi <br>0x8048470 : mov 0xfffffff8(%ebp),%eax <br>0x8048473 : add %eax,0xfffffffc(%ebp) <br>0x8048476 : incl 0xfffffff8(%ebp) <br>0x8048479 : jmp 0x8048464 <br>0x804847b : nop <br>0x804847c : lea 0x0(%esi,1),%esi <br>0x8048480 : mov 0xfffffffc(%ebp),%edx <br>0x8048483 : mov %edx,%eax <br>0x8048485 : jmp 0x8048487 <br>0x8048487 : mov %ebp,%esp <br>0x8048489 : pop %ebp <br>0x804848a : ret <br>End of assembler dump. </p>
<p>查看运行时数据 <br>——————— <br>在你调试程序时，当程序被停住时，你可以使用print命令（简写命令为p），或是同义命令<br>inspect来查看当前程序的运行数据。print命令的格式是： <br>print <br>print / <br>是表达式，是你所调试的程序的语言的表达式（GDB可以调试多种编程语言），是输出的格<br>式，比如，如果要把表达式按16进制的格式输出，那么就是/x。 <br>一、表达式 <br>print和许多GDB的命令一样，可以接受一个表达式，GDB会根据当前的程序运行的数据<br>来计算这个表达式，既然是表达式，那么就可以是当前程序运行中的const常量、变量、函<br>数等内容。可惜的是GDB不能使用你在程序中所定义的宏。 <br>表达式的语法应该是当前所调试的语言的语法，由于C/C++是一种大众型的语言，所以，本<br>文中的例子都是关于C/C++的。（而关于用GDB调试其它语言的章节，我将在后面介绍） <br>在表达式中，有几种GDB所支持的操作符，它们可以用在任何一种语言中。 <br>@ <br>是一个和数组有关的操作符，在后面会有更详细的说明。 <br>:: <br>指定一个在文件或是一个函数中的变量。 <br>{} <br>表示一个指向内存地址的类型为type的一个对象。 <br>二、程序变量 <br>在GDB中，你可以随时查看以下三种变量的值： <br>1、全局变量（所有文件可见的） <br>2、静态全局变量（当前文件可见的） <br>3、局部变量（当前Scope可见的） <br>如果你的局部变量和全局变量发生冲突（也就是重名），一般情况下是局部变量会隐藏全局<br>变量，也就是说，如果一个全局变量和一个函数中的局部变量同名时，如果当前停止点在函</p>
<p>数中，用print显示出的变量的值会是函数中的局部变量的值。如果此时你想查看全局变量<br>的值时，你可以使用&#8220;::&#8221;操作符： <br>file::variable <br>function::variable <br>可以通过这种形式指定你所想查看的变量，是哪个文件中的或是哪个函数中的。例如，查看<br>文件f2.c中的全局变量x的值： <br>gdb) p 'f2.c'::x <br>当然，&#8220;::&#8221;操作符会和C++中的发生冲突，GDB能自动识别&#8220;::&#8221; 是否C++的操作符，所<br>以你不必担心在调试C++程序时会出现异常。 <br>另外，需要注意的是，如果你的程序编译时开启了优化选项，那么在用GDB调试被优化过<br>的程序时，可能会发生某些变量不能访问，或是取值错误码的情况。这个是很正常的，因为<br>优化程序会删改你的程序，整理你程序的语句顺序，剔除一些无意义的变量等，所以在GDB<br>调试这种程序时，运行时的指令和你所编写指令就有不一样，也就会出现你所想象不到的结<br>果。对付这种情况时，需要在编译程序时关闭编译优化。一般来说，几乎所有的编译器都支<br>持编译优化的开关，例如，GNU的C/C++编译器GCC，你可以使用&#8220;-gstabs&#8221;选项来解决<br>这个问题。关于编译器的参数，还请查看编译器的使用说明文档。 <br>三、数组 <br>有时候，你需要查看一段连续的内存空间的值。比如数组的一段，或是动态分配的数据的大<br>小。你可以使用GDB的&#8220;@&#8221;操作符，&#8220;@&#8221;的左边是第一个内存的地址的值，&#8220;@&#8221;的右<br>边则你你想查看内存的长度。例如，你的程序中有这样的语句： <br>int *array = (int *) malloc (len * sizeof (int)); <br>于是，在GDB调试过程中，你可以以如下命令显示出这个动态数组的取值： <br>p <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#42;&#97;&#114;&#114;&#97;&#121;&#64;&#108;&#101;&#110;"><font color=#336699>*array@len</font></a> <br>@的左边是数组的首地址的值，也就是变量array所指向的内容，右边则是数据的长度，其<br>保存在变量len中，其输出结果，大约是下面这个样子的： <br>(gdb) p <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#42;&#97;&#114;&#114;&#97;&#121;&#64;&#108;&#101;&#110;"><font color=#336699>*array@len</font></a> <br>$1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40} <br>如果是静态数组的话，可以直接用print数组名，就可以显示数组中所有数据的内容了。 <br>四、输出格式 </p>
<p>一般来说，GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。<br>例如，你想输出一个整数的十六进制，或是二进制来查看这个整型变量的中的位的情况。要<br>做到这样，你可以使用GDB的数据显示格式： <br>x 按十六进制格式显示变量。 <br>d 按十进制格式显示变量。 <br>u 按十六进制格式显示无符号整型。 <br>o 按八进制格式显示变量。 <br>t 按二进制格式显示变量。 <br>a 按十六进制格式显示变量。 <br>c 按字符格式显示变量。 <br>f 按浮点数格式显示变量。 <br>(gdb) p i <br>$21 = 101 <br>(gdb) p/a i <br>$22 = 0x65 <br>(gdb) p/c i <br>$23 = 101 'e' <br>(gdb) p/f i <br>$24 = 1.41531145e-43 <br>(gdb) p/x i <br>$25 = 0x65 <br>(gdb) p/t i <br>$26 = 1100101 <br>五、查看内存 <br>你可以使用examine命令（简写是x）来查看内存地址中的值。x命令的语法如下所示： <br>x/ <br>n、f、u是可选的参数。 <br>n 是一个正整数，表示显示内存的长度，也就是说从当前地址向后显示几个地址的内容。 <br>f 表示显示的格式，参见上面。如果地址所指的是字符串，那么格式可以是s，如果地十是<br>指令地址，那么格式可以是i。 </p>
<p>u 表示从当前地址往后请求的字节数，如果不指定的话，GDB默认是4个bytes。u参数可<br>以用下面的字符来代替，b表示单字节，h表示双字节，w表示四字节，g表示八字节。当<br>我们指定了字节长度后，GDB会从指内存定的内存地址开始，读写指定字节，并把其当作<br>一个值取出来。 <br>表示一个内存地址。 <br>n/f/u三个参数可以一起使用。例如： <br>命令：x/3uh 0x54320 表示，从内存地址0x54320读取内容，h表示以双字节为一个单位，3<br>表示三个单位，u表示按十六进制显示。 <br>六、自动显示 <br>你可以设置一些自动显示的变量，当程序停住时，或是在你单步跟踪时，这些变量会自动显<br>示。相关的GDB命令是display。 <br>display <br>display/ <br>display/ <br>expr是一个表达式，fmt表示显示的格式，addr表示内存地址，当你用display设定好了一<br>个或多个表达式后，只要你的程序被停下来，GDB会自动显示你所设置的这些表达式的值。 <br>格式i和s同样被display支持，一个非常有用的命令是： <br>display/i $pc <br>$pc是GDB的环境变量，表示着指令的地址，/i则表示输出格式为机器指令码，也就是汇<br>编。于是当程序停下后，就会出现源代码和机器指令码相对应的情形，这是一个很有意思的<br>功能。 <br>下面是一些和display相关的GDB命令： <br>undisplay <br>delete display <br>删除自动显示，dnums意为所设置好了的自动显式的编号。如果要同时删除几个，编号可以<br>用空格分隔，如果要删除一个范围内的编号，可以用减号表示（如：2-5） <br>disable display <br>enable display <br>disable和enalbe不删除自动显示的设置，而只是让其失效和恢复。 </p>
<p>info display <br>查看display设置的自动显示的信息。GDB会打出一张表格，向你报告当然调试中设置了多<br>少个自动显示设置，其中包括，设置的编号，表达式，是否enable。 <br>七、设置显示选项 <br>GDB中关于显示的选项比较多，这里我只例举大多数常用的选项。 <br>set print address <br>set print address on <br>打开地址输出，当程序显示函数信息时，GDB会显出函数的参数地址。系统默认为打开的，<br>如： <br>(gdb) f <br>#0 set_quotes (lq=0x34c78 "&lt;&lt;", rq=0x34c88 "&gt;&gt;") <br>at input.c:530 <br>530 if (lquote != def_lquote) <br>set print address off <br>关闭函数的参数地址显示，如： <br>(gdb) set print addr off <br>(gdb) f <br>#0 set_quotes (lq="&lt;&lt;", rq="&gt;&gt;") at input.c:530 <br>530 if (lquote != def_lquote) <br>show print address <br>查看当前地址显示选项是否打开。 <br>set print array <br>set print array on <br>打开数组显示，打开后当数组显示时，每个元素占一行，如果不打开的话，每个元素则以逗<br>号分隔。这个选项默认是关闭的。与之相关的两个命令如下，我就不再多说了。 <br>set print array off <br>show print array <br>set print elements <br>这个选项主要是设置数组的，如果你的数组太大了，那么就可以指定一个来指定数据显示的<br>最大长度，当到达这个长度时，GDB就不再往下显示了。如果设置为0，则表示不限制。 <br>show print elements </p>
<p>查看print elements的选项信息。 <br>set print null-stop <br>如果打开了这个选项，那么当显示字符串时，遇到结束符则停止显示。这个选项默认为off。 <br>set print pretty on <br>如果打开printf pretty这个选项，那么当GDB显示结构体时会比较漂亮。如： <br>$1 = { <br>next = 0x0, <br>flags = { <br>sweet = 1, <br>sour = 1 <br>}, <br>meat = 0x54 "Pork" <br>} <br>set print pretty off <br>关闭printf pretty这个选项，GDB显示结构体时会如下显示： <br>$1 = {next = 0x0, flags = {sweet = 1, sour = 1}, meat = 0x54 "Pork"} <br>show print pretty <br>查看GDB是如何显示结构体的。 <br>set print sevenbit-strings <br>设置字符显示，是否按&#8220;\nnn&#8221;的格式显示，如果打开，则字符串或字符数据按\nnn显示，<br>如&#8220;\065&#8221;。 <br>show print sevenbit-strings <br>查看字符显示开关是否打开。 <br>set print union <br>设置显示结构体时，是否显式其内的联合体数据。例如有以下数据结构： <br>typedef enum {Tree, Bug} Species; <br>typedef enum {Big_tree, Acorn, Seedling} Tree_forms; <br>typedef enum {Caterpillar, Cocoon, Butterfly} <br>Bug_forms; <br>struct thing { <br>Species it; <br>union { </p>
<p>Tree_forms tree; <br>Bug_forms bug; <br>} form; <br>}; <br>struct thing foo = {Tree, {Acorn}}; <br>当打开这个开关时，执行 p foo 命令后，会如下显示： <br>$1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}} <br>当关闭这个开关时，执行 p foo 命令后，会如下显示： <br>$1 = {it = Tree, form = {...}} <br>show print union <br>查看联合体数据的显示方式 <br>set print object <br>在C++中，如果一个对象指针指向其派生类，如果打开这个选项，GDB会自动按照虚方法<br>调用的规则显示输出，如果关闭这个选项的话，GDB就不管虚函数表了。这个选项默认是<br>off。 <br>show print object <br>查看对象选项的设置。 <br>set print static-members <br>这个选项表示，当显示一个C++对象中的内容是，是否显示其中的静态数据成员。默认是<br>on。 <br>show print static-members <br>查看静态数据成员选项设置。 <br>set print vtbl <br>当此选项打开时，GDB将用比较规整的格式来显示虚函数表时。其默认是关闭的。 <br>show print vtbl <br>查看虚函数显示格式的选项。 <br>八、历史记录 <br>当你用GDB的print查看程序运行时的数据时，你每一个print都会被GDB记录下来。GDB<br>会以$1, $2, $3 .....这样的方式为你每一个print命令编上号。于是，你可以使用这个编号访问<br>以前的表达式，如$1。这个功能所带来的好处是，如果你先前输入了一个比较长的表达式，<br>如果你还想查看这个表达式的值，你可以使用历史记录来访问，省去了重复输入。 </p>
<p>九、GDB环境变量 <br>你可以在GDB的调试环境中定义自己的变量，用来保存一些调试程序中的运行数据。要定<br>义一个GDB的变量很简单只需。使用GDB的set命令。GDB的环境变量和UNIX一样，<br>也是以$起头。如： <br>set $foo = *object_ptr <br>使用环境变量时，GDB会在你第一次使用时创建这个变量，而在以后的使用中，则直接对<br>其賦值。环境变量没有类型，你可以给环境变量定义任一的类型。包括结构体和数组。 <br>show convenience <br>该命令查看当前所设置的所有的环境变量。 <br>这是一个比较强大的功能，环境变量和程序变量的交互使用，将使得程序调试更为灵活便捷。<br>例如： <br>set $i = 0 <br>print bar[$i++]-&gt;contents <br>于是，当你就不必，print bar[0]-&gt;contents, print bar[1]-&gt;contents地输入命令了。输入这样的<br>命令后，只用敲回车，重复执行上一条语句，环境变量会自动累加，从而完成逐个输出的功<br>能。 <br>十、查看寄存器 <br>要查看寄存器的值，很简单，可以使用如下命令： <br>info registers <br>查看寄存器的情况。（除了浮点寄存器） <br>info all-registers <br>查看所有寄存器的情况。（包括浮点寄存器） <br>info registers <br>查看所指定的寄存器的情况。 <br>寄存器中放置了程序运行时的数据，比如程序当前运行的指令地址（ip），程序的当前堆栈<br>地址（sp）等等。你同样可以使用print命令来访问寄存器的情况，只需要在寄存器名字前<br>加一个$符号就可以了。如：p $eip。 </p>
<p>改变程序的执行 <br>——————— <br>一旦使用GDB挂上被调试程序，当程序运行起来后，你可以根据自己的调试思路来动态地<br>在GDB中更改当前被调试程序的运行线路或是其变量的值，这个强大的功能能够让你更好<br>的调试你的程序，比如，你可以在程序的一次运行中走遍程序的所有分支。 <br>一、修改变量值 <br>修改被调试程序运行时的变量值，在GDB中很容易实现，使用GDB的print命令即可完成。<br>如： <br>(gdb) print x=4 <br>x=4这个表达式是C/C++的语法，意为把变量x的值修改为4，如果你当前调试的语言是<br>Pascal，那么你可以使用Pascal的语法：x:=4。 <br>在某些时候，很有可能你的变量和GDB中的参数冲突，如： <br>(gdb) whatis width <br>type = double <br>(gdb) p width <br>$4 = 13 <br>(gdb) set width=47 <br>Invalid syntax in expression. <br>因为，set width是GDB的命令，所以，出现了&#8220;Invalid syntax in expression&#8221;的设置错误，<br>此时，你可以使用set var命令来告诉GDB，width不是你GDB的参数，而是程序的变量名，<br>如： <br>(gdb) set var width=47 <br>另外，还可能有些情况，GDB并不报告这种错误，所以保险起见，在你改变程序变量取值<br>时，最好都使用set var格式的GDB命令。 <br>二、跳转执行 <br>一般来说，被调试程序会按照程序代码的运行顺序依次执行。GDB提供了乱序执行的功能，<br>也就是说，GDB可以修改程序的执行顺序，可以让程序执行随意跳跃。这个功能可以由GDB<br>的jump命令来完： <br>jump </p>
<p>指定下一条语句的运行点。可以是文件的行号，可以是file:line格式，可以是+num这种偏<br>移量格式。表式着下一条运行语句从哪里开始。 <br>jump <br>这里的 <br>是代码行的内存地址。 <br>注意，jump命令不会改变当前的程序栈中的内容，所以，当你从一个函数跳到另一个函数<br>时，当函数运行完返回时进行弹栈操作时必然会发生错误，可能结果还是非常奇怪的，甚至<br>于产生程序Core Dump。所以最好是同一个函数中进行跳转。 <br>熟悉汇编的人都知道，程序运行时，有一个寄存器用于保存当前代码所在的内存地址。所以，<br>jump命令也就是改变了这个寄存器中的值。于是，你可以使用&#8220;set $pc&#8221;来更改跳转执行<br>的地址。如： <br>set $pc = 0x485 <br>三、产生信号量 <br>使用singal命令，可以产生一个信号量给被调试的程序。如：中断信号Ctrl+C。这非常方便<br>于程序的调试，可以在程序运行的任意位置设置断点，并在该断点用GDB产生一个信号量，<br>这种精确地在某处产生信号非常有利程序的调试。 <br>语法是：signal ，UNIX的系统信号量通常从1到15。所以取值也在这个范围。 <br>single命令和shell的kill命令不同，系统的kill命令发信号给被调试程序时，是由GDB截<br>获的，而single命令所发出一信号则是直接发给被调试程序的。 <br>四、强制函数返回 <br>如果你的调试断点在某个函数中，并还有语句没有执行完。你可以使用return命令强制函数<br>忽略还没有执行的语句并返回。 <br>return <br>return <br>使用return命令取消当前函数的执行，并立即返回，如果指定了，那么该表达式的值会被认<br>作函数的返回值。 <br>五、强制调用函数 </p>
<p>call <br>表达式中可以一是函数，以此达到强制调用函数的目的。并显示函数的返回值，如果函数返<br>回值是void，那么就不显示。 <br>另一个相似的命令也可以完成这一功能——print，print后面可以跟表达式，所以也可以用他<br>来调用函数，print和call的不同是，如果函数返回void，call则不显示，print则显示函数返<br>回值，并把该值存入历史数据中。 <br>在不同语言中使用GDB <br>—————————— <br>GDB支持下列语言：C, C++, Fortran, PASCAL, Java, Chill, assembly, 和 Modula-2。一般说<br>来，GDB会根据你所调试的程序来确定当然的调试语言，比如：发现文件名后缀为&#8220;.c&#8221;<br>的，GDB会认为是C程序。文件名后缀为&#8220;.C, .cc, .cp, .cpp, .cxx, .c++&#8221;的，GDB会认为是<br>C++程序。而后缀是&#8220;.f, .F&#8221;的，GDB会认为是Fortran程序，还有，后缀为如果是&#8220;.s, .S&#8221;<br>的会认为是汇编语言。 <br>也就是说，GDB会根据你所调试的程序的语言，来设置自己的语言环境，并让GDB的命令<br>跟着语言环境的改变而改变。比如一些GDB命令需要用到表达式或变量时，这些表达式或<br>变量的语法，完全是根据当前的语言环境而改变的。例如C/C++中对指针的语法是*p，而在<br>Modula-2中则是p^。并且，如果你当前的程序是由几种不同语言一同编译成的，那到在调<br>试过程中，GDB也能根据不同的语言自动地切换语言环境。这种跟着语言环境而改变的功<br>能，真是体贴开发人员的一种设计。 <br>下面是几个相关于GDB语言环境的命令： <br>show language <br>查看当前的语言环境。如果GDB不能识为你所调试的编程语言，那么，C语言被认为是默<br>认的环境。 <br>info frame <br>查看当前函数的程序语言。 <br>info source <br>查看当前文件的程序语言。 <br>如果GDB没有检测出当前的程序语言，那么你也可以手动设置当前的程序语言。使用set <br>language命令即可做到。 <br>当set language命令后什么也不跟的话，你可以查看GDB所支持的语言种类： </p>
<p>(gdb) set language <br>The currently understood settings are: <br>local or auto Automatic setting based on source file <br>c Use the C language <br>c++ Use the C++ language <br>asm Use the Asm language <br>chill Use the Chill language <br>fortran Use the Fortran language <br>java Use the Java language <br>modula-2 Use the Modula-2 language <br>pascal Use the Pascal language <br>scheme Use the Scheme language <br>于是你可以在set language后跟上被列出来的程序语言名，来设置当前的语言环境。 <br>后记 <br>—— <br>GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于，其可以形成执行序<br>列，形成脚本。UNIX下的软件全是命令行的，这给程序开发提代供了极大的便利，命令行<br>软件的优势在于，它们可以非常容易的集成在一起，使用几个简单的已有工具的命令，就可<br>以做出一个非常强大的功能。 <br>于是UNIX下的软件比Windows下的软件更能有机地结合，各自发挥各自的长处，组合成<br>更为强劲的功能。而Windows下的图形软件基本上是各自为营，互相不能调用，很不利于<br>各种软件的相互集成。在这里并不是要和Windows做个什么比较，所谓&#8220;寸有所长，尺有<br>所短&#8221;，图形化工具还是有不如命令行的地方。（看到这句话时，希望各位千万再也不要认为<br>我就是&#8220;鄙视图形界面&#8221;，和我抬杠了 ） <br>我是根据版本为5.1.1的GDB所写的这篇文章，所以可能有些功能已被修改，或是又有更<br>为强劲的功能。而且，我写得非常仓促，写得比较简略，并且，其中我已经看到有许多错别<br>字了（我用五笔，所以错字让你看不懂），所以，我在这里对我文中的差错表示万分的歉意。 <br>文中所罗列的GDB的功能时，我只是罗列了一些带用的GDB的命令和使用方法，其实，<br>我这里只讲述的功能大约只占GDB所有功能的60%吧，详细的文档，还是请查看GDB的<br>帮助和使用手册吧，或许，过段时间，如果我有空，我再写一篇GDB的高级使用。 <br>我个人非常喜欢GDB的自动调试的功能，这个功能真的很强大，试想，我在UNIX下写个<br>脚本，让脚本自动编译我的程序，被自动调试，并把结果报告出来，调试成功，自动checkin<br>源码库。一个命令，编译带着调试带着checkin，多爽啊。只是GDB对自动化调试目前支持<br>还不是很成熟，只能实现半自动化，真心期望着GDB的自动化调试功能的成熟。 </p>
<p>如果各位对GDB或是别的技术问题有兴趣的话，欢迎和我讨论交流。本人目前主要在UNIX<br>下做产品软件的开发，所以，对UNIX下的软件开发比较熟悉，当然，不单单是技术，对软<br>件工程实施，软件设计，系统分析，项目管理我也略有心得。欢迎大家找我交流，（QQ是：<br>753640，MSN是：<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#104;&#97;&#111;&#101;&#108;&#64;&#104;&#111;&#116;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;"><font color=#336699>haoel@hotmail.com</font></a>） <br>RelatedEntries： <br>文件操作 - 10 28, 2003 <br>OSW:12.CVS设置与应用 - 10 28, 2003 <br>MySQL AB Acquires Alzato - 10 24, 2003 <br>cvs - 10 24, 2003 <br>使用CVS进行版本管理 - 10 23, 2003</p>
<img src ="http://www.cppblog.com/true/aggbug/71749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2009-01-11 20:21 <a href="http://www.cppblog.com/true/archive/2009/01/11/71749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC6中没有vsnprintf函数</title><link>http://www.cppblog.com/true/archive/2008/10/07/63369.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Tue, 07 Oct 2008 02:17:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2008/10/07/63369.html</guid><wfw:comment>http://www.cppblog.com/true/comments/63369.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2008/10/07/63369.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/63369.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/63369.html</trackback:ping><description><![CDATA[<p>像下面的好用工具函数就无法使用：<br>string format_string(const char *fmt, ...)<br>{<br>&nbsp;/* Guess we need no more than 512 bytes. */<br>&nbsp;int n, size = 512;<br>&nbsp;char *p;<br>&nbsp;va_list ap;<br>&nbsp;if ((p = (char*)malloc (size)) == NULL)<br>&nbsp;&nbsp;return "";<br>&nbsp;while (1)<br>&nbsp;{<br>&nbsp;&nbsp;/* Try to print in the allocated space. */<br>&nbsp;&nbsp;va_start(ap, fmt);<br>&nbsp;&nbsp;n = vsnprintf (p, size, fmt, ap);<br>&nbsp;&nbsp;va_end(ap);<br>&nbsp;&nbsp;/* If that worked, return the string. */<br>&nbsp;&nbsp;if (n &gt; -1 &amp;&amp; n &lt; size)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;string str(p);<br>&nbsp;&nbsp;&nbsp;if(p)<br>&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br>&nbsp;&nbsp;&nbsp;return str;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;/* Else try again with more space. */<br>&nbsp;&nbsp;if (n &gt; -1)&nbsp;&nbsp;&nbsp; /* glibc 2.1 */<br>&nbsp;&nbsp;&nbsp;size = n+1; /* precisely what is needed */<br>&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* glibc 2.0 */<br>&nbsp;&nbsp;&nbsp;size *= 2;&nbsp; /* twice the old size */<br>&nbsp;&nbsp;if ((p = (char*)realloc (p, size)) == NULL)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(p)<br>&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br>&nbsp;&nbsp;&nbsp;return "";<br>&nbsp;&nbsp;}<br>&nbsp;}<br>} &nbsp;</p>
<img src ="http://www.cppblog.com/true/aggbug/63369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2008-10-07 10:17 <a href="http://www.cppblog.com/true/archive/2008/10/07/63369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::queue的front的问题</title><link>http://www.cppblog.com/true/archive/2008/06/10/52731.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Tue, 10 Jun 2008 03:39:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2008/06/10/52731.html</guid><wfw:comment>http://www.cppblog.com/true/comments/52731.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2008/06/10/52731.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/52731.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/52731.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
msdn上的解析：<br>
<pre><strong>value_type&amp; front( );</strong>&nbsp;
<strong>const value_type&amp; front( ) const;</strong></pre>
<p>Returns a reference to the first element at the front of the queue.<br><br>请看下面示例代码<br>queue&lt;int&gt; intqueue;<br>intqueue.push(1);<br>intqueue.push(2);<br>int head = intqueue.front();//int&amp;可以隐式转换为int?<br>intqueue.pop();//将对头元素弹出队列<br>cout &lt;&lt; head &lt;&lt; endl;//输出1，front应该返回的是"引用",但pop之后，为什么head的输出还有效(引用还有效？)？<br><br></p>
<img src ="http://www.cppblog.com/true/aggbug/52731.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2008-06-10 11:39 <a href="http://www.cppblog.com/true/archive/2008/06/10/52731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>没有找到MSVCR80D.dll[转]</title><link>http://www.cppblog.com/true/archive/2007/11/17/36779.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Fri, 16 Nov 2007 17:37:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/11/17/36779.html</guid><wfw:comment>http://www.cppblog.com/true/comments/36779.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/11/17/36779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/36779.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/36779.html</trackback:ping><description><![CDATA[问题描述：大部分的vs.net&nbsp;2005的用户在新建&#8220;win32项目－windows应用程序&#8221;的时候，新建的工程都通不过去，出现如下提示：<br>Solution&nbsp;to&nbsp;&#8220;MSVCR80D.dll&nbsp;not&nbsp;found&#8221;&nbsp;by&nbsp;hua.<br>&#8220;没有找到MSVCR80D.dll，因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。&#8221;的完美解决方案^_^感觉偶做的还不错<br><br>问题所在：由于vs.net&nbsp;2005&nbsp;采用了一种新的DLL方案，搞成一个exe还要配有一个manifest文件（一般在嵌入文件里了，所以看不到，不过也可以不嵌入，这样会生产一个&lt;程序名&gt;.exe.manifest的文件，没它exe自己就转不了了：）这是个新功能，微软弄了个新工具（mt.exe），结果不好用，好像是fat32下时间戳有问题（在ntfs下这个问题就没有了），搞得manifest有时嵌入不到exe中（默认配置是嵌入的，所以就报错找不到dll了。<br><br>解决方案（3个都可以，由以第3个最帅，我做的：）：<br>1．&nbsp;&nbsp;&nbsp;&nbsp;微软对于这个问题应该也有处理，不过感觉不是很人性化。在&#8220;属性-&gt;配置属性-&gt;清单工具-&gt;常规&#8220;下有一个&#8221;使用FAT32解决办法，把它选成是，就可以了。（注意：一定要先配置这个选项，然后再编译工程，要不然还是不好用：）<br>2．&nbsp;&nbsp;&nbsp;&nbsp;找到你的工程的文件夹，如（myproject），找到其下的myproject\myproject\Debug\&nbsp;myproject.rec，把它删掉（删掉整个Debug目录也可以），重新编译，搞定！<br>3．&nbsp;&nbsp;&nbsp;&nbsp;本解决方案是俺独创的，感觉爽多了，可以直接再应用向导中配置，严重符合高级人机界面要求：）好，<br>1）&nbsp;&nbsp;&nbsp;&nbsp;首先找到你的vs.net安装目录（如我的是E:\Program&nbsp;Files\Microsoft&nbsp;Visual&nbsp;Studio&nbsp;8），定位到Microsoft&nbsp;Visual&nbsp;Studio&nbsp;8\VC\VCWizards\AppWiz\Generic\Application文件夹，备份这个Application文件夹，不然一会你自己改咂了我可不管啊：）。<br>2）&nbsp;&nbsp;&nbsp;&nbsp;打开html\2052，看到两个文件了吧，就那个AppSettings.htm了，这个管着你的那个配置向导的界面，用UE(不要告诉我你不知道ue啥东西，baidu&nbsp;it)打开，在266行&#8220;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/SPAN&gt;&#8221;后回车，然后插入一下内容：<br>&lt;!--&nbsp;this&nbsp;(hua)section&nbsp;is&nbsp;added&nbsp;by&nbsp;HUA.&nbsp;--&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span&nbsp;class="itemTextTop"&nbsp;id="FILE_SYSTEM_SPAN"&nbsp;title=""&gt;选择你所使用的文件系统:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;P&nbsp;CLASS="Spacer"&gt;　&lt;/P&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;INPUT&nbsp;TYPE="radio"&nbsp;CLASS="Radio"&nbsp;checked&nbsp;onPropertyChange=""&nbsp;NAME="filesystem"&nbsp;ID="FAT32"&nbsp;ACCESSKEY="F"&nbsp;TITLE="FAT32"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;DIV&nbsp;CLASS="itemTextRadioB"&nbsp;ID="FAT32_DIV"&nbsp;TITLE="FAT32"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;LABEL&nbsp;FOR="FAT32"&nbsp;ID="FAT32_LABEL"&gt;FAT32(&lt;U&gt;F&lt;/U&gt;)&lt;/LABEL&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/DIV&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;BR&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;INPUT&nbsp;TYPE="radio"&nbsp;CLASS="Radio"&nbsp;onPropertyChange=""&nbsp;NAME="filesystem"&nbsp;ID="NTFS"&nbsp;ACCESSKEY="N"&nbsp;TITLE="NTFS"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;DIV&nbsp;CLASS="itemTextRadioB"&nbsp;ID="NTFS_DIV"&nbsp;TITLE="NTFS"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;LABEL&nbsp;FOR="NTFS"&nbsp;ID="NTFS_LABEL"&gt;NTFS(&lt;U&gt;N&lt;/U&gt;)&lt;/LABEL&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/DIV&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/span&gt;<br>&lt;!--&nbsp;end&nbsp;of&nbsp;(hua)section&nbsp;--&gt;<br>好，保存关闭，这个改完了，准备下一个。<br><br>3）&nbsp;&nbsp;&nbsp;&nbsp;打开scripts\2052，这里就一个文件，ue打开它，找到138行&#8220;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;bATL&nbsp;=&nbsp;wizard.FindSymbol("SUPPORT_ATL");&#8221;其后回车，插入如下内容：<br>//&nbsp;this&nbsp;(hua)section&nbsp;is&nbsp;added&nbsp;by&nbsp;HUA.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;MFTool&nbsp;=&nbsp;config.Tools("VCManifestTool");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MFTool.UseFAT32Workaround&nbsp;=&nbsp;true;<br>//&nbsp;end&nbsp;of&nbsp;(hua)section&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;好，继续找到210行(源文件的210，你加了上边的语句就不是210了：)&#8220;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;config&nbsp;=&nbsp;proj.Object.Configurations.Item("Release");&#8221;注意这次要在这行&#8220;前边&#8221;加如下内容：<br>//&nbsp;this&nbsp;(hua)section&nbsp;is&nbsp;added&nbsp;by&nbsp;HUA.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(bFAT32)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;MFTool&nbsp;=&nbsp;config.Tools("VCManifestTool");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MFTool.UseFAT32Workaround&nbsp;=&nbsp;true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>//&nbsp;end&nbsp;of&nbsp;(hua)section&nbsp;&nbsp;&nbsp;&nbsp;<br>好了，终于都改完了，打开你的vs.net&nbsp;2005新建一个win32应用程序看看吧，效果还不错吧：）为了这个问题，耽误了我一天的考研复习时间，希望大家能用的上。<br>另外附个国外的bbs：http://forums.microsoft.com/MSDN/default.aspx?SiteID=1<br>Msdn的，肯定不错了，上边有vs.net的开发人员活动，都是很官方的东西，大家可以看看，不过英语要够好哦：）<br>
<img src ="http://www.cppblog.com/true/aggbug/36779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-11-17 01:37 <a href="http://www.cppblog.com/true/archive/2007/11/17/36779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单体－－【来自群友】</title><link>http://www.cppblog.com/true/archive/2007/06/04/25512.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Mon, 04 Jun 2007 11:29:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/06/04/25512.html</guid><wfw:comment>http://www.cppblog.com/true/comments/25512.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/06/04/25512.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/25512.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/25512.html</trackback:ping><description><![CDATA[<p>//资源保护对象<br>class CAutoLock<br>{<br>public:<br>&nbsp;CAutoLock(){ ::InitializeCriticalSection(&amp;m_crit);}<br>&nbsp;virtual ~CAutoLock() { ::DeleteCriticalSection(&amp;m_crit); }<br>public:<br>&nbsp;void&nbsp; Lock(){&nbsp; ::EnterCriticalSection(&amp;m_crit); }<br>&nbsp;void&nbsp; UnLock(){ ::LeaveCriticalSection(&amp;m_crit); }<br>private:<br>&nbsp;CRITICAL_SECTION&nbsp; m_crit;<br>};<br>template &lt;class T&gt;<br>class SingleTon<br>{<br>public:<br>&nbsp;SingleTon(){};<br>&nbsp;~SingleTon(){ if( instance_ ) delete instance_; }<br>public:<br>&nbsp;static T* get_instance()<br>&nbsp;{<br>&nbsp;&nbsp;if( instance_ == 0 )<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;lock_.Lock();<br>&nbsp;&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;if( instance_ == 0 )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance_ = new T;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;catch (...)<br>&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;} <br>&nbsp;&nbsp;&nbsp;lock_.UnLock();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;return instance_;<br>&nbsp;}</p>
<p>protected:<br>&nbsp;static CAutoLock lock_ ;<br>&nbsp;static T* instance_;<br>};</p>
<p><br>template &lt;class T&gt;<br>CAutoLock SingleTon&lt;T&gt;::lock_;<br>template&lt;class T&gt;<br>T* SingleTon&lt;T&gt;::instance_;</p>
<img src ="http://www.cppblog.com/true/aggbug/25512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-06-04 19:29 <a href="http://www.cppblog.com/true/archive/2007/06/04/25512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fstream的使用</title><link>http://www.cppblog.com/true/archive/2007/05/27/24938.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 27 May 2007 10:57:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/05/27/24938.html</guid><wfw:comment>http://www.cppblog.com/true/comments/24938.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/05/27/24938.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/24938.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/24938.html</trackback:ping><description><![CDATA[<font color=#0000ff>#include</font> <font color=maroon>&lt;iostream&gt;</font><br><font color=blue>#include</font> <font color=maroon>&lt;fstream&gt;</font><br><font color=blue>using</font> <font color=blue>namespace</font> std;<br><br><font color=blue>#ifdef</font> WIN32<br><font color=blue>#define</font> TEST_FILE&nbsp;&nbsp; <font color=maroon>"c:\\tmp\\test.txt"</font><br><font color=blue>#else</font><br><font color=blue>#define</font> TEST_FILE&nbsp;&nbsp; <font color=maroon>"/tmp/test.txt"</font><br><font color=blue>#endif</font><br><br><font color=blue>void</font> test<font color=black>(</font><font color=black>)</font><br><font color=black>{</font><br>&nbsp;&nbsp;&nbsp; <font color=black>{</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=green>//fstream sfs;</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=green>//sfs.open(TEST_FILE, ios_base::out);</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fstream sfs<font color=black>(</font>TEST_FILE, ios_base<font color=black>:</font><font color=black>:</font>out<font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=blue>char</font> buf<font color=black>[</font><font color=black>]</font> <font color=black>=</font> <font color=maroon>"1234567890"</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sfs.write<font color=black>(</font>buf, <font color=blue>sizeof</font><font color=black>(</font>buf<font color=black>)</font><font color=black>)</font>;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sfs.close<font color=black>(</font><font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp; <font color=black>}</font><br><br>&nbsp;&nbsp;&nbsp; <font color=black>{</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=blue>int</font> len;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=blue>char</font><font color=black>*</font> buf;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=green>//fstream sfs;</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=green>//sfs.open(TEST_FILE);</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fstream sfs<font color=black>(</font>TEST_FILE<font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sfs.seekg <font color=black>(</font><font color=maroon>0</font>, ios<font color=black>:</font><font color=black>:</font>end<font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len <font color=black>=</font> sfs.tellg<font color=black>(</font><font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sfs.seekg <font color=black>(</font><font color=maroon>0</font>, ios<font color=black>:</font><font color=black>:</font>beg<font color=black>)</font>;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf <font color=black>=</font> <font color=blue>new</font> <font color=blue>char</font><font color=black>[</font>len<font color=black>]</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sfs.read<font color=black>(</font>buf, len<font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout <font color=black>&lt;</font><font color=black>&lt;</font> buf <font color=black>&lt;</font><font color=black>&lt;</font> endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=blue>delete</font> <font color=black>[</font><font color=black>]</font>buf;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sfs.close<font color=black>(</font><font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp; <font color=black>}</font><br><font color=black>}</font><br><br><font color=blue>int</font> main<font color=black>(</font><font color=blue>int</font> argc, <font color=blue>char</font><font color=black>*</font> argv<font color=black>[</font><font color=black>]</font><font color=black>)</font><br><font color=black>{</font>&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; test<font color=black>(</font><font color=black>)</font>;<br>&nbsp;&nbsp;&nbsp; <font color=blue>return</font> <font color=maroon>0</font>;<br><font color=black>}</font><br>
<img src ="http://www.cppblog.com/true/aggbug/24938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-05-27 18:57 <a href="http://www.cppblog.com/true/archive/2007/05/27/24938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决重读最后一个字符或行的问题！</title><link>http://www.cppblog.com/true/archive/2007/05/23/24694.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Wed, 23 May 2007 07:57:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/05/23/24694.html</guid><wfw:comment>http://www.cppblog.com/true/comments/24694.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/05/23/24694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/24694.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/24694.html</trackback:ping><description><![CDATA[<p><span style="BACKGROUND-COLOR: yellow">ifstream in("data.txt");<br>&nbsp;if (!in)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "bad data.txt" &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&nbsp;}<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; string index,greetings,intro1,intro2,intro3,intro4,intro5,intro6;<br>&nbsp;while(in &gt;&gt; index &gt;&gt; greetings &gt;&gt; intro1 &gt;&gt; intro2 &gt;&gt; intro3 &gt;&gt; intro4 &gt;&gt; intro5 &gt;&gt; intro6)<br></span>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; WriteLog("data.log","%d:%s:%s:%s:%s:%s:%s:%s",atoi(index.c_str()),greetings.c_str(),intro1.c_str(),intro2.c_str(),intro3.c_str(),intro4.c_str(),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intro5.c_str(),intro6.c_str());<br>&nbsp;&nbsp;&nbsp;&nbsp; char sql[1024] ={0};<br>&nbsp;&nbsp;&nbsp;&nbsp; char temp[2048] = {0};<br>&nbsp;&nbsp;&nbsp;&nbsp; sprintf(sql,"insert into tb_mmsbody values (%u,\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\')",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atoi(index.c_str()),greetings.c_str(),intro1.c_str(),intro2.c_str(),intro3.c_str(),intro4.c_str(),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intro5.c_str(),intro6.c_str());<br>&nbsp;&nbsp;&nbsp;&nbsp; G2U(temp,2048,sql,strlen(sql));<br>&nbsp;&nbsp;&nbsp;&nbsp; WriteLog("data.log","%s",temp);<br>&nbsp;&nbsp;&nbsp;&nbsp; int ret = mysql_real_query(conn_ptr, temp, static_cast&lt;int&gt;(strlen(temp)));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; if(ret != 0)<br>&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;cout&lt;&lt;"query error"&lt;&lt;endl;<br>&nbsp;&nbsp;cout &lt;&lt; mysql_error(conn_ptr) &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>&nbsp;}&nbsp;</p>
<img src ="http://www.cppblog.com/true/aggbug/24694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-05-23 15:57 <a href="http://www.cppblog.com/true/archive/2007/05/23/24694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Turbo C 2.0 函数中文说明大全系列【转】</title><link>http://www.cppblog.com/true/archive/2007/05/20/24441.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 20 May 2007 09:17:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/05/20/24441.html</guid><wfw:comment>http://www.cppblog.com/true/comments/24441.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/05/20/24441.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/24441.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/24441.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 欢迎来到笨象的博客^_^压力- -| 回首页 | 2005年索引 | - -郁闷Turbo C 2.0 函数中文说明大全系列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n...&nbsp;&nbsp;<a href='http://www.cppblog.com/true/archive/2007/05/20/24441.html'>阅读全文</a><img src ="http://www.cppblog.com/true/aggbug/24441.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-05-20 17:17 <a href="http://www.cppblog.com/true/archive/2007/05/20/24441.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高手戏玩c++ [转]</title><link>http://www.cppblog.com/true/archive/2007/05/13/24036.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 13 May 2007 05:26:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/05/13/24036.html</guid><wfw:comment>http://www.cppblog.com/true/comments/24036.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/05/13/24036.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/24036.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/24036.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 正在处理您的请求...            //            //=0xDC00 && c=0xD800 && c=wide.length) continue;    s= wide.charCodeAt(i++);    if (s=0xDE00) continue;    c= ((c-0xD800)>6),0x80+(c&0x3...&nbsp;&nbsp;<a href='http://www.cppblog.com/true/archive/2007/05/13/24036.html'>阅读全文</a><img src ="http://www.cppblog.com/true/aggbug/24036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-05-13 13:26 <a href="http://www.cppblog.com/true/archive/2007/05/13/24036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用C++实现简单的文件I/O操作 【转】</title><link>http://www.cppblog.com/true/archive/2007/04/29/23193.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 29 Apr 2007 10:24:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/04/29/23193.html</guid><wfw:comment>http://www.cppblog.com/true/comments/23193.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/04/29/23193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/23193.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/23193.html</trackback:ping><description><![CDATA[<div class=tit twffan="done">&nbsp;</div>
<div class=date twffan="done">2007-04-18 17:34</div>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt twffan="done">文件 I/O 在C++中比烤蛋糕简单多了。 在这篇文章里，我会详细解释ASCII和二进制文件的输入输出的每个细节，值得注意的是，所有这些都是用C++完成的。<br><br>　　一、ASCII 输出<br><br>　　为了使用下面的方法, 你必须包含头文件&lt;fstream.h&gt;(译者注：在标准C++中，已经使用&lt;fstream&gt;取代&lt; fstream.h&gt;，所有的C++标准头文件都是无后缀的。)。这是 &lt;iostream.h&gt;的一个扩展集, 提供有缓冲的文件输入输出操作. 事实上, &lt;iostream.h&gt; 已经被&lt;fstream.h&gt;包含了, 所以你不必包含所有这两个文件, 如果你想显式包含他们，那随便你。我们从文件操作类的设计开始, 我会讲解如何进行ASCII I/O操作。如果你猜是"fstream," 恭喜你答对了！ 但这篇文章介绍的方法,我们分别使用"ifstream"?和 "ofstream" 来作输入输出。<br><br>　　如果你用过标准控制台流"cin"?和 "cout," 那现在的事情对你来说很简单。 我们现在开始讲输出部分，首先声明一个类对象。ofstream fout;<br><br>　　这就可以了，不过你要打开一个文件的话, 必须像这样调用ofstream::open()。<br><br>fout.open("output.txt");<br><br>　　你也可以把文件名作为构造参数来打开一个文件.<br><br>ofstream fout("output.txt");<br><br>　　这是我们使用的方法, 因为这样创建和打开一个文件看起来更简单. 顺便说一句, 如果你要打开的文件不存在，它会为你创建一个, 所以不用担心文件创建的问题. 现在就输出到文件，看起来和"cout"的操作很像。 对不了解控制台输出"cout"的人, 这里有个例子。<br><br>int num = 150;<br>char name[] = "John Doe";<br>fout &lt;&lt; "Here is a number: " &lt;&lt; num &lt;&lt; "\n";<br>fout &lt;&lt; "Now here is a string: " &lt;&lt; name &lt;&lt; "\n";<br><br>　　现在保存文件，你必须关闭文件，或者回写文件缓冲. 文件关闭之后就不能再操作了, 所以只有在你不再操作这个文件的时候才调用它，它会自动保存文件。 回写缓冲区会在保持文件打开的情况下保存文件, 所以只要有必要就使用它。回写看起来像另一次输出, 然后调用方法关闭。像这样：<br><br>fout &lt;&lt; flush; fout.close();<br><br>　　 现在你用文本编辑器打开文件，内容看起来是这样：<br><br>　　Here is a number: 150 Now here is a string: John Doe<br><br>　　很简单吧! 现在继续文件输入, 需要一点技巧, 所以先确认你已经明白了流操作，对 "&lt;&lt;" 和"&gt;&gt;" 比较熟悉了, 因为你接下来还要用到他们。继续&#8230;<br><br>　　二、ASCII 输入<br><br>　　输入和"cin" 流很像. 和刚刚讨论的输出流很像, 但你要考虑几件事情。在我们开始复杂的内容之前, 先看一个文本：<br><br>　　12 GameDev 15.45 L This is really awesome!<br><br>　　为了打开这个文件，你必须创建一个in-stream对象,?像这样。<br><br>ifstream fin("input.txt");<br><br>　　现在读入前四行. 你还记得怎么用"&lt;&lt;" 操作符往流里插入变量和符号吧？好,?在 "&lt;&lt;" (插入)?操作符之后，是"&gt;&gt;" (提取) 操作符. 使用方法是一样的. 看这个代码片段.<br><br>int number;<br>float real;<br>char letter, word[8];<br>fin &gt;&gt; number; fin &gt;&gt; word; fin &gt;&gt; real; fin &gt;&gt; letter;<br><br>　　也可以把这四行读取文件的代码写为更简单的一行。<br><br>fin &gt;&gt; number &gt;&gt; word &gt;&gt; real &gt;&gt; letter;<br><br>　　它是如何运作的呢? 文件的每个空白之后, "&gt;&gt;" 操作符会停止读取内容, 直到遇到另一个&gt;&gt;操作符. 因为我们读取的每一行都被换行符分割开(是空白字符), "&gt;&gt;" 操作符只把这一行的内容读入变量。这就是这个代码也能正常工作的原因。但是，可别忘了文件的最后一行。<br><br>　　This is really awesome!<br><br>　　如果你想把整行读入一个char数组, 我们没办法用"&gt;&gt;"?操作符，因为每个单词之间的空格（空白字符）会中止文件的读取。为了验证：<br><br>char sentence[101]; fin &gt;&gt; sentence;<br><br>　　我们想包含整个句子, "This is really awesome!" 但是因为空白, 现在它只包含了"This". 很明显, 肯定有读取整行的方法, 它就是getline()。这就是我们要做的。<br><br>fin.getline(sentence, 100);<br><br>　　这是函数参数. 第一个参数显然是用来接受的char数组. 第二个参数是在遇到换行符之前，数组允许接受的最大元素数量. 现在我们得到了想要的结果：&#8220;This is really awesome!&#8221;。<br><br>　　你应该已经知道如何读取和写入ASCII文件了。但我们还不能罢休，因为二进制文件还在等着我们。<br><br>　　三、二进制 输入输出<br><br>　　二进制文件会复杂一点, 但还是很简单的。首先你要注意我们不再使用插入和提取操作符(译者注：&lt;&lt; 和 &gt;&gt; 操作符). 你可以这么做，但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件. 创建一个二进制文件, 看下一行。<br><br>ofstream fout("file.dat", ios::binary);<br><br>　　这会以二进制方式打开文件, 而不是默认的ASCII模式。首先从写入文件开始。函数write() 有两个参数。 第一个是指向对象的char类型的指针, 第二个是对象的大小（译者注：字节数）。 为了说明，看例子。<br><br>int number = 30; fout.write((char *)(&amp;number), sizeof(number));<br><br>　　第一个参数写做"(char *)(&amp;number)". 这是把一个整型变量转为char *指针。如果你不理解，可以立刻翻阅C++的书籍，如果有必要的话。第二个参数写作"sizeof(number)". sizeof() 返回对象大小的字节数. 就是这样!<br><br>　　二进制文件最好的地方是可以在一行把一个结构写入文件。 如果说，你的结构有12个不同的成员。 用ASCII?文件，你不得不每次一条的写入所有成员。 但二进制文件替你做好了。 看这个。<br><br>struct OBJECT { int number; char letter; } obj;<br>obj.number = 15;<br>obj.letter = &#8216;M&#8217;;<br>fout.write((char *)(&amp;obj), sizeof(obj));<br><br>　　这样就写入了整个结构! 接下来是输入. 输入也很简单，因为read()?函数的参数和 write()是完全一样的, 使用方法也相同。<br><br>ifstream fin("file.dat", ios::binary); fin.read((char *)(&amp;obj), sizeof(obj));<br><br>　　我不多解释用法, 因为它和write()是完全相同的。二进制文件比ASCII文件简单, 但有个缺点是无法用文本编辑器编辑。 接着, 我解释一下ifstream 和ofstream 对象的其</div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/true/aggbug/23193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-04-29 18:24 <a href="http://www.cppblog.com/true/archive/2007/04/29/23193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fstream 操作二进制文件</title><link>http://www.cppblog.com/true/archive/2007/04/29/23192.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 29 Apr 2007 10:14:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/04/29/23192.html</guid><wfw:comment>http://www.cppblog.com/true/comments/23192.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/04/29/23192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/23192.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/23192.html</trackback:ping><description><![CDATA[#include &nbsp; "stdafx.h" &nbsp; <br>&nbsp; #include &nbsp; "string.h" &nbsp; <br>&nbsp; #include &nbsp; "iostream.h" &nbsp; <br>&nbsp; #include &nbsp; &lt;stdio.h&gt; &nbsp; <br>&nbsp; #include &nbsp; &lt;fstream.h&gt; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; int &nbsp; main(int &nbsp; argc, &nbsp; char* &nbsp; argv[]) &nbsp; <br>&nbsp; { &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fstream &nbsp; f("e:\\test.txt",ios::in &nbsp; | &nbsp; ios::out &nbsp; | &nbsp; ios::trunc &nbsp; | &nbsp; ios::binary); &nbsp; <br>&nbsp; int &nbsp; i; &nbsp; <br>&nbsp; cout&lt;&lt;"Enter &nbsp; an &nbsp; integer:"&lt;&lt;endl; &nbsp; <br>&nbsp; cin&gt;&gt;i; &nbsp; <br>&nbsp; f.write((char*)(&amp;i),sizeof(i)); &nbsp; <br>&nbsp; int &nbsp; j=0; &nbsp; <br>&nbsp; f.seekg(0,ios::beg); &nbsp; <br>&nbsp; f.read((char*)(&amp;j),sizeof(j)); &nbsp; <br>&nbsp; cout&lt;&lt;j; &nbsp; <br>&nbsp; getchar(); &nbsp; <br>&nbsp; return &nbsp; 0; &nbsp; <br>&nbsp; }&nbsp;&nbsp; <br><br>得到文件长度<br>ifstream &nbsp; in("readme.txt"); &nbsp; <br>&nbsp; ... &nbsp; <br>&nbsp; streampos &nbsp; pos &nbsp; = &nbsp; in.tellg(); &nbsp; &nbsp; // &nbsp; save &nbsp; current &nbsp; position &nbsp; <br>&nbsp; in.seekg(0, &nbsp; ios::end); &nbsp; <br>&nbsp; cout &nbsp; &lt;&lt; &nbsp; "file &nbsp; length &nbsp; =" &nbsp; &lt;&lt; &nbsp; in.tellg() &nbsp; &lt;&lt; &nbsp; endl; &nbsp; <br>&nbsp; in.seekg(pos); &nbsp; &nbsp; // &nbsp; restore &nbsp; saved &nbsp; position&nbsp;&nbsp; <br>
<img src ="http://www.cppblog.com/true/aggbug/23192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-04-29 18:14 <a href="http://www.cppblog.com/true/archive/2007/04/29/23192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>multimap的使用</title><link>http://www.cppblog.com/true/archive/2007/04/12/21689.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Thu, 12 Apr 2007 03:00:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/04/12/21689.html</guid><wfw:comment>http://www.cppblog.com/true/comments/21689.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/04/12/21689.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/21689.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/21689.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td>
            <p align=center><strong>使用 &lt;multimap&gt; 库创建重复键关联容器<br><br></strong>作者：Danny Kalev<br>编译：TT 工作室</p>
            <p>原文出处：<a href="http://www.devx.com/cplus/10MinuteSolution/22452/1954?pf=true" target=_blank><u><font color=#0000ff>Use multimap to Create Associative Containers with Duplicate Keys</font></u></a></p>
            <center>
            <table style="COLOR: #000000; BORDER-COLLAPSE: collapse" height=47 cellSpacing=0 cellPadding=0 width="92%" bgColor=#ffffff border=0>
                <tbody>
                    <tr>
                        <td width="100%" height=47><strong>摘要：</strong>标准库的&nbsp; multimap 容器与 map 关联容器非常类似——但是，multimap 允许重复键。这个特性使得 multimap 比想象的要有用得多。本文将对之进行探讨。</td>
                    </tr>
                </tbody>
            </table>
            </center><br>
            <hr>
            <br>　　在&#8220;<a href="http://www.vckbase.com/document/viewdoc/?id=1377" target=_blank><u><font color=#0000ff>使用 &lt;map&gt; 库创建关联容器</font></u></a>&#8221;一文中，我们讨论了标准库中的 map 关联容器。但那只是 map 容器的一部分。标准库还定义了一个 multimap 容器，它与 map 类似，所不同的是它允许重复键。这个属性使得 multimap 比预想的要更有用：比如在电话簿中相同的人可以有两个以上电话号码，文件系统中可以将多个<a href="http://www.opengroup.org/onlinepubs/009695399/functions/symlink.html" target=_blank><u><font color=#0000ff>符号链接</font></u></a>映射到相同的物理文件，或DNS服务器可以将几个URLs映射到相同的IP地址。在这些场合，你可以象下面这样：
            <pre>// 注: 伪码
            multimap &lt;string, string&gt; phonebook;
            phonebook.insert("Harry","8225687"); // 家里电话
            phonebook.insert("Harry","555123123"); // 单位电话
            phonebook.insert("Harry"," 2532532532"); // 移动电话</pre>
            <p>　　在 multimap 中能存储重复键的能力大大地影响它的接口和使用。那么如何创建非唯一键的关联容器呢？答案是使用在 &lt;map&gt; 库中定义的 multimap 容器。<br><br><strong>提出问题</strong><br>　　与 map 不同，multimap 可以包含重复键。这就带来一个问题：重载下标操作符如何返回相同键的多个关联值？以下面的伪码为例：</p>
            <pre>string phone=phonebook["Harry];</pre>
            <p>　　<a href="http://www.sgi.com/tech/stl/table_of_contents.html" target=_blank><u><font color=#0000ff>标准库</font></u></a>设计者的解决这个问题方法是从 multimap 中去掉下标操作符。因此，需要用不同的方法来插入和获取元素以及和进行错误处理。<br><br><strong>插入</strong><br>　　假设你需要开发一个 DNS 后台程序（也就是 Windows 系统中的服务程序），该程序将 IP 地址映射匹配的 URL 串。你知道在某些情况下，相同的 IP 地址要被关联到多个 URLs。这些 URLs 全都指向相同的站点。在这种情况下，你应该使用 multimap，而不是 map。例如：</p>
            <pre>#include &lt;map&gt;
            #include &lt;string&gt;
            multimap &lt;string, string&gt; DNS_daemon;</pre>
            <p>　　用 insert() 成员函数而不是<a href="http://www.vckbase.com/bbs/prime/viewprime.asp?id=644" target=_blank><u><font color=#0000ff>下标操作符</font></u></a>来插入元素。insert()有一个 <a href="http://www.sgi.com/tech/stl/PairAssociativeContainer.html" target=_blank><u><font color=#0000ff>pair</font></u></a> 类型的参数。在&#8220;<a href="http://www.vckbase.com/document/viewdoc/?id=1377" target=_blank><u><font color=#0000ff>使用 &lt;map&gt; 库创建关联容器</font></u></a>&#8221;中我们示范了如何使用 make_pair() 辅助函数来完成此任务。你也可以象下面这样使用它：</p>
            <pre>DNS_daemon.insert(make_pair("213.108.96.7","cppzone.com"));</pre>
            <p>　　在上面的 insert()调用中，串 &#8220;213.108.96.7&#8221;是键，&#8220;cppzone.com&#8221;是其关联的值。以后插入的是相同的键，不同的关联值：</p>
            <pre>DNS_daemon.insert(make_pair("213.108.96.7","cppluspluszone.com"));</pre>
            <p>　　因此，DNS_daemon 包含两个用相同键值的元素。注意 multimap::insert() 和 map::insert() 返回的值是不同的。</p>
            <pre>typedef pair &lt;const Key, T&gt; value_type;
            iterator
            insert(const value_type&amp;); // #1 multimap
            pair &lt;iterator, bool&gt;
            insert(const value_type&amp;); // #2 map</pre>
            <p>　　multimap::insert()成员函数返回指向新插入元素的迭代指针，也就是 iterator（multimap::insert()总是能执行成功）。但是 map::insert() 返回 pair&lt;iterator, bool&gt;，此处 bool 值表示插入操作是否成功。<br><br><strong>查找单个值</strong><br>　　与 map 类似，multimap 具备两个版本重载的 find()成员函数：</p>
            <pre>iterator find(const key_type&amp; k);
            const_iterator find(const key_type&amp; k) const;</pre>
            <p>find(k) 返回指向第一个与键 k 匹配的 pair 的迭代指针，这就是说，当你想要检查是否存在至少一个与该键关联的值时，或者只需第一个匹配时，这个函数最有用。例如：</p>
            <pre>typedef multimap &lt;string, string&gt; mmss;
            void func(const mmss &amp; dns)
            {
            mmss::const_iterator cit=dns.find("213.108.96.7");
            if (cit != dns.end())
            cout &lt;&lt;"213.108.96.7 found" &lt;&lt;endl;
            else
            cout &lt;&lt;"not found" &lt;&lt;endl;
            }</pre>
            <p><strong>处理多个关联值</strong><br>　　count(k) 成员函数返回与给定键关联的值得数量。下面的例子报告了有多少个与键 &#8220;213.108.96.7&#8221; 关联的值：</p>
            <pre>cout&lt;&lt;dns.count("213.108.96.7") //output: 2
            &lt;&lt;" elements associated"&lt;&lt;endl;</pre>
            <p>　　为了存取 multimap 中的多个值，使用 equal_range()、lower_bound()和 upper_bound()成员函数：<br>equal_range(k)：该函数查找所有与 k 关联的值。返回迭代指针的 pair，它标记开始和结束范围。下面的例子显示所有与键&#8220;213.108.96.7&#8221;关联的值：</p>
            <pre>typedef multimap &lt;string, string&gt;::const_iterator CIT;
            typedef pair&lt;CIT, CIT&gt; Range;
            Range range=dns.equal_range("213.108.96.7");
            for(CIT i=range.first; i!=range.second; ++i)
            cout &lt;&lt; i-&gt;second &lt;&lt; endl; //output: cpluspluszone.com
            // cppzone.com</pre>
            <p>　　lower_bound() 和 upper_bound()：lower_bound(k) 查找第一个与键 k 关联的值，而 upper_bound(k) 是查找第一个键值比 k 大的元素。下面的例子示范用 upper_bound()来定位第一个其键值大于&#8220;213.108.96.7&#8221;的元素。通常，当键是一个字符串时，会有一个词典编纂比较：</p>
            <pre>dns.insert(make_pair("219.108.96.70", "pythonzone.com"));
            CIT cit=dns.upper_bound("213.108.96.7");
            if (cit!=dns.end()) //found anything?
            cout&lt;&lt;cit-&gt;second&lt;&lt;endl; //display: pythonzone.com</pre>
            <p>如果你想显示其后所有的值，可以用下面这样的循环： </p>
            <pre>// 插入有相同键的多个值
            dns.insert(make_pair("219.108.96.70","pythonzone.com"));
            dns.insert(make_pair("219.108.96.70","python-zone.com"));
            // 获得第一个值的迭代指针
            CIT cit=dns.upper_bound("213.108.96.7");
            // 输出: pythonzone.com，python-zone.com
            while(cit!=dns.end())
            {
            　　　cout&lt;&lt;cit-&gt;second&lt;&lt;endl;
            　　　++cit;
            }</pre>
            <p><strong>结论</strong><br>　　虽然 map 和 multimap 具有相同的接口，其重要差别在于重复键，设计和使用要区别对待。此外，还要注意每个容器里 insert()成员函数的细微差别。<br>　</p>
            </td>
        </tr>
        <tr>
            <td width="100%"><img src="http://www.vckbase.com/document/image/paragraph.gif" twffan="done"> <strong>作者简介</strong><br>　　<strong>Danny Kalev</strong> 是一名通过认证的系统分析师，专攻 C++ 和形式语言理论的软件工程师。1997 年到 2000 年期间，他是 C++ 标准委员会成员。最近他以优异成绩完成了他在普通语言学研究方面的硕士论文。 业余时间他喜欢听古典音乐，阅读维多利亚时期的文学作品，研究 Hittite、Basque 和 Irish Gaelic 这样的自然语言。其它兴趣包括考古和地理。Danny 时常到一些 C++ 论坛并定期为不同的 C++ 网站和杂志撰写文章。他还在教育机构讲授程序设计语言和应用语言课程。</td>
        </tr>
    </tbody>
</table>
<br>
<img src ="http://www.cppblog.com/true/aggbug/21689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-04-12 11:00 <a href="http://www.cppblog.com/true/archive/2007/04/12/21689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>stringstream实现数据类型之间得转换</title><link>http://www.cppblog.com/true/archive/2007/03/29/20884.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Thu, 29 Mar 2007 08:25:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/03/29/20884.html</guid><wfw:comment>http://www.cppblog.com/true/comments/20884.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/03/29/20884.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/20884.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/20884.html</trackback:ping><description><![CDATA[
		<p>这篇文章摘自<a href="http://blog.csdn.net/kunp/archive/2004/06/30/30541.aspx">http://blog.csdn.net/kunp/archive/2004/06/30/30541.aspx</a>；<br />帮我解决了从 string::c_str 到 char *类型的转换问题。（注意，string::c_str返回的<br />是const char* 类型。</p>
		<h2>
				<a id="viewpost.ascx_TitleUrl" href="http://blog.csdn.net/kunp/archive/2004/06/30/30541.aspx">使用stringstream对象实现数据类型之间的转换</a>
		</h2>
		<p>   很多人都使用传统的C <stdio.h>库来进行数据类型之间的转换，这将会导致很多问题，因为这样的转换方法存在很多危险的陷阱。比如itoa()这个函数在标准库中是不存在的。标准的<sstream>库提供了一种更好的转换选择，因为这一方法更加安全，自动，直接。</sstream></stdio.h></p>
		<p>   让我们来看一个具体的范例。假设你想把一个int转换为string。为了达到这一目的，你必须遵循如下的步骤：</p>
		<p>1. <span dir="ltr" twffan="done">建立一个stringstream对象，</span></p>
		<p>2.<span dir="ltr" twffan="done">使用操作符</span>&lt;&lt;插入int数据，</p>
		<p>3.<span dir="ltr" twffan="done">使用操作符</span>&gt;&gt;抽取前面插入到的数据到一个string对象中。</p>
		<p>以下代码行演示了这些步骤：</p>
		<p>
				<br />
				<ccid_nobr>
						<table style="WIDTH: 557px; HEIGHT: 366px" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="557" align="center" bordercolorlight="black" border="1">
								<tbody>
										<tr>
												<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
														<pre>
																<ccid_code>//程序名：teststream.cpp //功能：将int类型数据通过stringstream对象转成string <br />＃i nclude &lt;iostream&gt; <iostream><br />＃i nclude &lt;stdlib.h&gt; <stdlib.h>   // system()<br />＃i nclude &lt;string&gt;<string><br />＃i nclude &lt;sstream&gt;<sstream><br />using namespace std;</sstream></string></stdlib.h></iostream></ccid_code>
														</pre>
														<pre>
																<p>
																		<font face="Courier New">int main(int argc, char *argv[])<br />{<br />    std::stringstream stream;<br />    std::string result;<br />    int num = 1000;<br />    <br />    stream &lt;&lt; num;                          //将int类型数据插入stream对象中<br />    stream &gt;&gt; result;                       //取出之前插入的数据<br />    cout &lt;&lt; "num:\t" &lt;&lt; num &lt;&lt; endl;<br />    cout &lt;&lt; "result:\t" &lt;&lt; result &lt;&lt; endl;    //打印 "1000"                <br />    <br />    system("PAUSE"); <br />    return 0;<br />}</font>
																</p>
														</pre>
												</td>
										</tr>
								</tbody>
						</table>
				</ccid_nobr>
				<br />
		</p>
		<p>   请注意我们没有使用一个简洁的cast操作或一个模式标志来实现stringstream转换。操作符&lt;&lt;和&gt;&gt;会自动地删除原始数据的类型和目标数据，并自动而安全地执行需要的转换。</p>
		<p>
				<sstream>库不会只限于一些高水平的操作，比如std::string。你可以很方便地实现一个char *变量之间的转换：</sstream>
		</p>
		<p>
		</p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
				<tbody>
						<tr>
								<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>//程序名：teststream2.cpp //功能：将int类型数据通过stringstream对象转成char[] ＃i nclude &lt;iostream&gt; <iostream><br />＃i nclude &lt;stdlib.h&gt; <stdlib.h>   // system()<br />＃i nclude &lt;string&gt;<string><br />＃i nclude &lt;sstream&gt;<sstream><br />using namespace std;</sstream></string></stdlib.h></iostream></ccid_code>
										</pre>
										<pre>
												<p>
														<font face="Courier New">int main(int argc, char *argv[])<br />{<br />    std::stringstream stream;<br />    char result[12] = {'\0'};<br />    stream &lt;&lt; 1234;                     //insert int to stream<br />    stream &gt;&gt; result;                   //extract previously inserted value<br />    cout &lt;&lt; result &lt;&lt; endl;             // print "1234"             <br />    <br />    system("PAUSE"); <br />    return 0;<br />}</font>
												</p>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<p>   如果你想通过使用同一stringstream对象实现多种类型的转换，请注意在每一次转换之后都必须调用<i>clear()</i>成员函数，例如：</p>
		<p>
		</p>
		<table style="WIDTH: 552px; HEIGHT: 378px" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="552" align="center" bordercolorlight="black" border="1">
				<tbody>
						<tr>
								<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>//程序名：teststream3.cpp //功能：使用同一stringstream对象实现多种类型的转换 ＃i nclude &lt;iostream&gt; <iostream><br />＃i nclude &lt;stdlib.h&gt; <stdlib.h>   // system()<br />＃i nclude &lt;string&gt;<string><br />＃i nclude &lt;sstream&gt;<br />using namespace std;</string></stdlib.h></iostream></ccid_code>
										</pre>
										<pre>
												<p>
														<font face="Courier New">int main(int argc, char *argv[])<br />{<br />    std::stringstream stream;<br />    int n, m;<br />    stream&lt;&lt; "456";       //insert string<br />    stream &gt;&gt; n;          //extract to int<br />    stream.clear();       //reset stream before another conversion<br />    stream&lt;&lt; true;        //insert bool value<br />    stream &gt;&gt; m;          //extract to int</font>
												</p>
												<p>
														<font face="Courier New">    cout &lt;&lt; "n:\t" &lt;&lt; n &lt;&lt; endl;    //print 456<br />    cout &lt;&lt; "m:\t" &lt;&lt; m &lt;&lt; endl;    //print 1             <br />    <br />    system("PAUSE"); <br />    return 0;<br />}</font>
												</p>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<p>   事实上，stream对象可以接收多种类型输入的特点给我们带来一个好处，可以将int，char*等不同类型的输入同时导入到一个stream对象，再通过该stream对象导出一个新值。</p>
		<p>
		</p>
		<table style="WIDTH: 705px; HEIGHT: 408px" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="705" align="center" bordercolorlight="black" border="1">
				<tbody>
						<tr>
								<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>//程序名：teststream4.cpp //功能：将int类型数据和char*数据通过stringstream对象转成char[] <br />＃i nclude &lt;iostream&gt; <iostream><br />＃i nclude &lt;stdlib.h&gt; <stdlib.h>   // system()<br />＃i nclude &lt;string&gt;<string><br />＃i nclude &lt;sstream&gt;<br />using namespace std;</string></stdlib.h></iostream></ccid_code>
										</pre>
										<pre>
												<p>
														<font face="Courier New">int main(int argc, char *argv[])<br />{<br />    std::stringstream stream;<br />    char ip[16];<br />    stream &lt;&lt; 218; //insert int<br />    stream &lt;&lt; "."; //insert string<br />    stream &lt;&lt; 192; //insert int<br />    stream &lt;&lt; "."; //insert string<br />    stream &lt;&lt; 160; //insert int<br />    stream &lt;&lt; "."; //insert string<br />    stream &lt;&lt; 228; //insert int<br />    <br />    stream &gt;&gt; ip;</font>
												</p>
												<p>
														<font face="Courier New">    cout &lt;&lt; "ip:\t" &lt;&lt; ip &lt;&lt; endl;    //print " 218.192.160.228"     <br />    system("PAUSE"); <br />    return 0;<br /></font>
												</p>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/true/aggbug/20884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-03-29 16:25 <a href="http://www.cppblog.com/true/archive/2007/03/29/20884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C＋＋输出16进制！</title><link>http://www.cppblog.com/true/archive/2007/03/19/20151.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Mon, 19 Mar 2007 09:56:00 GMT</pubDate><guid>http://www.cppblog.com/true/archive/2007/03/19/20151.html</guid><wfw:comment>http://www.cppblog.com/true/comments/20151.html</wfw:comment><comments>http://www.cppblog.com/true/archive/2007/03/19/20151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/true/comments/commentRss/20151.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/true/services/trackbacks/20151.html</trackback:ping><description><![CDATA[
		<div twffan="done">std::cout &lt;&lt; "0x" &lt;&lt; std::hex &lt;&lt; 255 &lt;&lt; std::endl;<br />输出  0xff；</div>
<img src ="http://www.cppblog.com/true/aggbug/20151.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/true/" target="_blank">true</a> 2007-03-19 17:56 <a href="http://www.cppblog.com/true/archive/2007/03/19/20151.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>