﻿<?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++博客-blueskiner-随笔分类-C/C++</title><link>http://www.cppblog.com/blueskiner/category/19758.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 06 Aug 2014 02:36:34 GMT</lastBuildDate><pubDate>Wed, 06 Aug 2014 02:36:34 GMT</pubDate><ttl>60</ttl><item><title>网上转的一篇关于boost asio网络引擎开发的文章</title><link>http://www.cppblog.com/blueskiner/archive/2014/07/24/207768.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Thu, 24 Jul 2014 00:21:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2014/07/24/207768.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/207768.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2014/07/24/207768.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/207768.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/207768.html</trackback:ping><description><![CDATA[<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">今天找到了贵论坛，发现坛主的很多想法和本人不谋而合，本人近1年主要精力都致力于开发一个大型多人在线游戏的基本架构和相关的技术模组。而我欣喜的发现我与坛主的研究方向正好相反：我是先从服务器端开始研究入手的，目前服务器端告一段落，正准备开始客户端的研发，在寻找客户端引擎的时候碰巧找到了这里。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">我看到坛主的这个板块，了解到Orz正需要一些服务器方面的资料，在此我先奉上个人的服务器端的一些成果，希望能有所帮助。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">（一）自己开发的一个基于boost::asio的网络引擎</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">首先这个网络引擎是基于boost::asio的一个封装，网络部分功能非常底层，API只有基本的listen、connect、send、kick等（均为异步，目前只实现了TCP协议），而其他方面提供的是基于mysql的db接口和log接口，还有一个自己开发的对象池，用于使用FreeList的概念来事先分配内存，降低运行时期内存的分配时间；</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">另外就是开发了一个多线程下的数据结构，一个线程安全的map，这个map可以让无限个线程同时读和写（包括添加元素、删除元素、修改元素）而无需任何因为互斥锁定带来的线程等待等开销。即是说1000个线程和1个线程操作这个map的效率是相同的。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">发布形式：win32（64位未测试，但是开发考虑了相关的定制，例如指针和long在64位下从4字节提高到8字节，引擎底层做了数据类型的typedef）下 dll+lib+include；linux（Redhat、CentOS5.x，gcc3.4以上，需要安装boost1.37和mysql5.0）so+include；source code，yes，of course！</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">网络部分的基本结构是这样的：</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#1 io部分设计。一个线程池负责处理io，这个实际上就是一组boost::asio::io_service::run，每个boost::asio::io_service下有一组私有线程，负责处理异步io事件，这里，boost::asio::io_service得数量和其下私有线程的数量是可以根据配置文件自由设置的，如果你了解boost::asio，那么一定知道它推荐一个cpu对应一个boost::asio::io_service对象（或者一个boost::asio::io_service，但是每个boost::asio::io_service下的私有线程对应每个cpu），这样在多处理器（或者多核处理器）下效率可以达到最高；</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#2 complete handler设计。另一个线程池负责处理封装好的complete handler，即对应io事件的用户定义的逻辑处理，例如io recv事件，对应一个用户实现邦定的（使用boost::bind和boost::function）handler来处理当接受到socket消息的时候调用对应的handler（函数、仿函数对象、成员函数等）。#1和#2中的线程池之间使用一组线程安全的队列来传递消息（传递使用直接的值拷贝，不使用动态内存，因为动态内存的申请和释放太消耗时间，即便使用内存池也一样。1k以下的值拷贝的时间损耗都远远小于对应的动态内存申请的时间；另外使用值拷贝也有线程安全的考虑）；</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#3 封包的设计。head+body，head中有固定4字节的body长度信息（int32）和4字节的封包类型信息（int32），如果愿意，可以修改代码进行扩展（packet部分是独立于引擎的模块，也是一组dll,lib,include或者so,include），接受和发送由于是tcp，所以按照head中的body长度来控制一个封包的完整性。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#4 多线程模型。boss-worker模型，主要用于广播消息、查找、和db、log的实现上；生产者、消费者模型，主要用于#1和#2 的两个线程池之间的事件传递（io线程池产生completehandler，用户的线程池负责处理、消费）</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#5 session的设计。一个session就是一个成功连接进来的客户端socket代理，出于线程安全和效率的考虑，session的存储容器不使用任何stl和boost的容器，而是使用&#8212;&#8212;C的数组（当然不是静态数组，而是：new char[n]这样的），来实现。而且是二维数组，这样配合对象池（指与先分配好一组&#8220;空&#8221;的session），我们无需任何互斥变量就能够毫无阻碍的访问和修改数组中的每个元素（session），并发性能达到最大。至于二维数组的设计，第二维的值对应io线程池和用户线程池中的线程数量，即一个线程唯一邦定一组session，这是为了分配session id时候效率和安全的考虑。（例如id 0~9对应一组session，10~19是第二组，而每组id和session都唯一绑定一个线程）</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#6 线程之间数据传递的设计。线程安全的queue，使用了boost::thread::locks中的mutex、shared_mutex、condition_variable_any等概念，当queue空闲时，使用条件变量等待特定的事件（例如新的元素push进来，或者程序退出等）；</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#7 异步下session的唯一性。由于整体是异步的，所以不可避免的会出现当一个session的某个处理还未结束的时候，这个session已经消失了，甚至换了一个新的session（指id的分配），那么这个时候如果没有任何防范处理，之前的那个未完成的处理很可能会作用到这个新的session上，就不可避免的出现一些错误和未知情况，我们如何防范呢？使用valid_code，设计一个64位的无符号整型变量，给每个session按照事先给定的session总量（这个引擎使用预先分配内存方法，所以开始前必须手动指定session的最大数量&#8212;&#8212;通过配置文件），分配一个唯一的数据段（例如1~10000000，10000001~2000000等），每次这个session发现有新连接进来的socket使用了自己，则将自己的valid_code +1，当加到最大值的时候（例如刚才举例的10000000等），自动变为最小值（例如刚才的1等）。每个session的valid_code在引擎的初始化阶段是随机生成的（在事先指定好的数据段中随机）。再加上每个session的数据段时唯一的，所以不会产生重复的valid_code，这样鉴别某个时间段内唯一的session就成了可能；</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#8 agent基类的设计。这个其实就是封装了boost::thread类，即&#8220;带私有线程的类&#8221;，主要用于作为一些相对独立的工作，例如log记录、db访问处理、定期ping某个ip等，引擎中的logger和db接口都是继承自它；</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#9 db接口设计。一个数据库对应一个database对象，每个database对象拥有一个自己私有的线程池，其中线程的数量可以根据配置文件自由设定（例如和mysql的连接数量等，处理query的线程数量等）</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#10 一些零碎。BIG_ENDIAN问题，封包内部自动进行了处理，无须用户单独设置；跨平台以及不同编译器的预编译设置，以及不同cpu的针对处理（x86，powerpc等）</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">目前的不足之处：</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#1 并未开发完全。udp没有实现封装，当然boost::asio完全支持。logger目前只支持printf功能，对于写file和传递到专门的log服务器方面只留下了接口；封包加密以及安全方面是一个空白，目前的版本并未添加。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#2 面向底层，并不提供高层功能，所以很多开发都需要自己进行；（对，这并不是一个&#8220;网游引擎&#8221;）</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">#3 性能方面并未经过大量测试，由于本人工作较忙，这些都是业余时间搞得，所以只是初步测了一下连接并发部分：使用某个不知道配置的笔记本测得3秒并发连接1500。再多的并发连接并没有尝试过。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">PS 由于本人工作较忙，故只能提供源代码（只提供windows版，便于查看，linux可以直接使用源代码编译，gcc3.4以上boost1.37即可），文档方面一直没有时间整理，这篇文章都是中午抽空写的（零零散散修改到现在），所以暂时就写这么多把。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">PS2 提供的源代码是vs2005sln，只包含source code、配置和工程文件。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">PS3 我看到贵论坛在研究RakNet，据我的一个前同事说，他认为RakNet并不好，网络底层用的是select，而且不是异步，代码质量不高，建议我不要使用它的网络层。我感觉RakNet的一些高层功能还是可以参考的，例如安全加密、大厅分流等，至于网络底层，我建议还是用boost::asio，跨平台、性能和扩展性都很优秀，而且被C++标准委员会所支持，很被看好。</span><br style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;" /><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">作者：Nouness</span><img src ="http://www.cppblog.com/blueskiner/aggbug/207768.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2014-07-24 08:21 <a href="http://www.cppblog.com/blueskiner/archive/2014/07/24/207768.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ld: 0711-736 XCOFF64 object files are not allowed in 32-bit mode</title><link>http://www.cppblog.com/blueskiner/archive/2012/10/12/193216.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Fri, 12 Oct 2012 07:47:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2012/10/12/193216.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/193216.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2012/10/12/193216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/193216.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/193216.html</trackback:ping><description><![CDATA[编译BDB报错： 
<p>&#8230;&#8230;</p>
<p>Stop.<br />ld: 0711-736 ERROR: Input file jjkz_rcv.o:<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> XCOFF64 object files are not allowed in 32-bit mode.</p>
<p>&nbsp;<wbr></p>
<p>查了link，解决方法为在系统变量里加个参数：</p>
<p>export OBJECT_MODE=64<br /><br />编译过去了，可执行文件生成了。</p>
<p>还有报错，估计是程序的通用性问题。</p>
<p>记下来，便于以后查找。</p><img src ="http://www.cppblog.com/blueskiner/aggbug/193216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2012-10-12 15:47 <a href="http://www.cppblog.com/blueskiner/archive/2012/10/12/193216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xlC的64编译模式</title><link>http://www.cppblog.com/blueskiner/archive/2012/10/12/193215.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Fri, 12 Oct 2012 07:46:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2012/10/12/193215.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/193215.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2012/10/12/193215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/193215.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/193215.html</trackback:ping><description><![CDATA[<span style="font-size: 10px">&nbsp; 
<h3 id="ruopt64b"><a name="t0"></a><span style="font-weight: normal">在AIX上编译64位的库基本上有两个方法一个是设置OBJECT_MODE环境变量，另一个是使用-q64的编译选项。</span><span style="font-weight: normal"><span style="font-size: 8px"></h3>
<p><strong style="font-size: 12pt">关于OBJECT_MODE环境变量：</strong></p>
<p><span style="font-size: 12pt">The&nbsp;</span><span style="font-size: 12pt">AIX</span><span style="font-size: 12pt">&nbsp;operating system provides support for the&nbsp;</span><span class="pk"><span style="font-size: 12pt">OBJECT_MODE</span></span><span style="font-size: 12pt">&nbsp;environment variable to enable the user to obtain a 64-bit development environment.&nbsp;</span><span style="font-size: 12pt">AIX</span><span style="font-size: 12pt">&nbsp;tools use the setting of&nbsp;</span><span class="pk"><span style="font-size: 12pt">OBJECT_MODE</span></span><span style="font-size: 12pt">&nbsp;to determine the type of object to be used or created. The&nbsp;</span><span class="pk"><span style="font-size: 12pt">OBJECT_MODE</span></span><span style="font-size: 12pt">&nbsp;environment variable has three recognized settings:</span></p>
<dl>
<dt class="bold"><span class="pk"><span style="font-size: 12pt">OBJECT_MODE</span></span><span style="font-size: 12pt" class="pk">=32</span></dt>
<dd><span style="font-size: 12pt">Works with 32-bit objects</span></dd>
<dt class="bold"><span class="pk"><span style="font-size: 12pt">OBJECT_MODE</span></span><span style="font-size: 12pt" class="pk">=64</span></dt>
<dd><span style="font-size: 12pt">Works with 64-bit objects</span></dd>
<dt class="bold"><span class="pk"><span style="font-size: 12pt">OBJECT_MODE</span></span><span style="font-size: 12pt" class="pk">=32_64</span></dt>
<dd><span style="font-size: 12pt">Works with either 32-bit or 64-bit objects</span></dd></dl></span></span>
<p>&nbsp;</p>
<h3><a name="t1"></a>&nbsp;</h3>
<h3><a name="t2"></a>关于-q64:</h3>
<h3><a name="t3"></a>-q32, -q64</h3><a name="wq273"></a>
<h4 id="wq273"><a name="t4"></a>Description</h4>
<p><span style="font-size: 12pt">Selects either 32-bit or 64-bit compiler mode.</span></p><a id="skipsyn-15" name="skipsyn-15"></a><a name="wq275"></a>
<h4 id="wq275"><a name="t5"></a>Notes</h4>
<p><span style="font-size: 12pt">The&nbsp;<span style="font-size: 12pt" class="bold">-q32</span></span><span style="font-size: 12pt">&nbsp;and&nbsp;<span style="font-size: 12pt" class="bold">-q64</span></span><span style="font-size: 12pt">&nbsp;options override the compiler mode set by the value of the OBJECT_MODE environment variable, if it exists.</span><span style="font-size: 12pt">&nbsp;If this option is not explicitly specified on the command line,&nbsp;</span><span style="font-size: 12pt">and the OBJECT_MODE environment variable is not set,</span><span style="font-size: 12pt">&nbsp;the compiler will default to 32-bit output mode.</span></p>
<p><span style="font-size: 12pt">If the compiler is invoked in 64-bit mode, the&nbsp;</span><span style="font-size: 12pt">__<span style="font-size: 12pt">64BIT</span></span><span style="font-size: 12pt">__</span><span style="font-size: 12pt">&nbsp;preprocessor macro is defined.</span></p></span><img src ="http://www.cppblog.com/blueskiner/aggbug/193215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2012-10-12 15:46 <a href="http://www.cppblog.com/blueskiner/archive/2012/10/12/193215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)C/C++字符串查找函数</title><link>http://www.cppblog.com/blueskiner/archive/2012/08/01/185840.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Wed, 01 Aug 2012 00:23:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2012/08/01/185840.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/185840.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2012/08/01/185840.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/185840.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/185840.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">C/C++ string库（string.h）提供了几个字符串查找函数，如下：</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "></p><table border="1" cellpadding="1" cellspacing="1" height="158" width="545" style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px; text-align: left; background-color: #ffffff; "><tbody><tr><td>memchr</td><td>在指定内存里定位给定字符</td></tr><tr><td>strchr</td><td>在指定字符串里定位给定字符</td></tr><tr><td>strcspn</td><td>返回在字符串str1里找到字符串str2里的任意一个字符之前已查找的字符数量</td></tr><tr><td>strrchr</td><td>在字符串里定位给定字符最后一次出现的位置</td></tr><tr><td>strpbrk</td><td>在字符串str1里定位字符串str2里任意一个首次出现的字符</td></tr><tr><td>strspn</td><td>返回字符串str1从开始字符到第一个不在str2中的字符个数</td></tr><tr><td>strstr</td><td>在字符串str1中定位字符串str2首次出现的位置</td></tr></tbody></table><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">函数说明：</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">1、memchr</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：const void * memchr ( const void * ptr, int value, size_t num);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void * memchr ( void * ptr, int value, size_t num);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：ptr，待查找的内存指针；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value，要查找的值；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num，内存大小。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">说明：在ptr指向的内存中查找value，返回指向和value首次匹配的元素指针，如果没有找到，返回NULL指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">2、strchr</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：const char * strchr ( const char * str, int character);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * strchr ( char * str, int character);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：str，待查找字符串指针；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; character，要查找的值。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">说明：在字符串str中查找character，返回指向和character首次匹配的元素指针，如果没有找到，返回NULL指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">3、strcspn</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：size_t strcspn ( const char * str1, const char * str2);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：str1，待查找的字符串指针；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str2，要查找的字符串指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">说明：在str1中查找str2中的字符，返回找到str2中任意一个字符时已查找的字符个数。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">4、strrchr</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：const char * strrchr ( const char * str, int character);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * strrchr ( char * str, int character);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：str，待查找的字符串指针；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; character，要查找的值。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">说明：在str中查找character，返回指向与character最后一次匹配的元素的指针，如果没有找到，返回NULL指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">5、strpbrk</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：const char * strpbrk (const char * str1, const char * str2);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * strpbrk ( char * str1, const char * str2);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：在str1中查找str2中任意一个字符，返回指向与首次出现的str2中的任意一个字符匹配的元素的指针，如果没有找到，返回NULL指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">6、strspn</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：size_t strspn ( const char * str1, const char * str2);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：str1，待查找的字符串指针；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str2，要查找的字符串指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">说明：从str1的第一个字符开始算起，直到出现一个不在str2中的字符为止，返回字符个数。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; "><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">7、strstr</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">原型：const char * strstr ( const char * str1, cosnt char *str2);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * strstr ( char * str1, const char * str2);</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">参数：str1，待查找的字符串指针；</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str2，要查找的字符串指针。</p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">说明：在str1中查找匹配str2的子串，并返回指向首次匹配时的第一个元素指针。如果没有找到，返回NULL指针。</p><img src ="http://www.cppblog.com/blueskiner/aggbug/185840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2012-08-01 08:23 <a href="http://www.cppblog.com/blueskiner/archive/2012/08/01/185840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unix/Linux如何遍历一个目录下所有的文件</title><link>http://www.cppblog.com/blueskiner/archive/2012/07/29/185529.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Sun, 29 Jul 2012 02:05:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2012/07/29/185529.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/185529.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2012/07/29/185529.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/185529.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/185529.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;网络上流传一种方案，用opendir(), readdir(),closedir()方式解决。我也尝试使用，发现不能解决我的需求。这种方案，仅仅能遍历给出所有的文件名，估计效率比较高吧。一旦遍历中需要对文件进行操作就会发生意想不到的事情，比如进入了死循环，程序一直在while readdir()中纠结。下面贴上网络上流传的这段代码：<br />
<p>#include &lt;sys/types.h&gt;<br />#include &lt;sys/stat.h&gt;<br />#include &lt;unistd.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;stdio.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;dirent.h&gt;<br />int testdir(char *path)<br />{<br />&nbsp;struct stat buf;<br />&nbsp;if(lstat(path,&amp;buf)&lt;0)<br />&nbsp;{<br />&nbsp;&nbsp;return 0;<br />&nbsp;}<br />&nbsp;if(S_ISDIR(buf.st_mode))<br />&nbsp;{<br />&nbsp;&nbsp;return 1; //directory<br />&nbsp;}<br />&nbsp;return 0;<br />}</p>
<p><br />int directory(char *path)<br />{<br />&nbsp;DIR *db;<br />&nbsp;char filename[128];<br />&nbsp;struct dirent *p;<br />&nbsp;db=opendir(path);<br />&nbsp;if(db==NULL)return 0;<br />&nbsp;memset(filename,0,128);<br />&nbsp;while ((p=readdir(db)))<br />&nbsp;{<br />&nbsp;&nbsp;if((strcmp(p-&gt;d_name,".")==0)||(strcmp(p-&gt;d_name,"..")==0))<br />&nbsp;&nbsp;&nbsp;continue;<br />&nbsp;&nbsp;else<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;sprintf(filename,"%s/%s",path,p-&gt;d_name); <br />&nbsp;&nbsp;&nbsp;if(testdir(filename))<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;directory(filename);<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;else {<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%s/n",filename);<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;memset(filename,0,64);<br />&nbsp;}<br />&nbsp;closedir(db);<br />&nbsp;return 0;<br />}<br />int main(int argc,char **argv)<br />{<br />&nbsp;char *path="./"; //要遍历的目录<br />&nbsp;if(access(path,F_OK)==0&amp;&amp;testdir(path))<br />&nbsp;{<br />&nbsp;&nbsp;printf("is directory/n");<br />&nbsp;&nbsp;directory(path);<br />&nbsp;}<br />&nbsp;else printf("%s not exist/n",path);<br />}<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后来我又找到了另外还有一种方案，这种方案能帮我解决不能打开文件进行操作的疑惑。主要是使用ftw.h里的方法，该头文件意义是 file tree wall文件目录树遍历：先贴上代码：<br /></p>
<p><br />#include &lt;iostream&gt;<br />#include &lt;fstream&gt;<br />using namespace std;</p>
<p>#include &lt;string.h&gt;<br />#include &lt;ftw.h&gt;</p>
<p>int fn(const char* file, const struct stat* sb, int flag)<br />{<br />&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; line[256] = {0};<br />&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; count = 0;</p>
<p>&nbsp;&nbsp;&nbsp; if (flag == FTW_F) {&nbsp;&nbsp;&nbsp; // 如果是文件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"The File's name : "&lt;&lt;file&lt;&lt;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ifstream file(file);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file.isopen()) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.getline(line, 100);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;line&lt;&lt;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE*&nbsp;&nbsp; fp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fp = fopen(file, "r");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fgets(line, sizeof(line), fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose(fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Line's data######## : %s\n", line);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }else if (flag == FTW_D) {&nbsp; // 如果是子目录(遍历的第一个是根目录)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"The Directory name : "&lt;&lt;file&lt;&lt;endl;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return 0;<br />}</p>
<p>int main(int argc, char** argv)<br />{<br />&nbsp;&nbsp;&nbsp; ftw("home/~", fn, 0);<br />&nbsp;&nbsp;&nbsp; return 0;<br />}<br /><br /><br /><br /><br /></p><img src ="http://www.cppblog.com/blueskiner/aggbug/185529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2012-07-29 10:05 <a href="http://www.cppblog.com/blueskiner/archive/2012/07/29/185529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于C++标准库string::substr的用法陷阱</title><link>http://www.cppblog.com/blueskiner/archive/2012/07/29/185528.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Sun, 29 Jul 2012 01:56:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2012/07/29/185528.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/185528.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2012/07/29/185528.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/185528.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/185528.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;今天由于项目中需要对一些文本做字符串处理后生成string，插入map。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;刚开始时，我就打算用std::string处理结果，久没用突显生疏啊，看到find_first_of()就望文生义了，调试了半天才发现这是对传入字符串的每个字符的查找函数，赶紧撤出，去cplusplus reference逛了逛，发现我用错了，应该使用find()才能解决我的需求，find已经轻车上路，问题又来了，到了截获字段这步了，当然，只能用substr()了，由于久没用到，对第二参数n传入的时候发生了错误认识，n应该是字符的计数，第一个参数应该是要截获的子字符串的头位置，我把第二个参数以结束位置的方式传入了，唉。。。怪不得调试了半天。。。说是陷阱，也是我马虎大意的表现啊。。。不应该，如果参数为count那就直观多了。这里又引申一个问题：变量命名，其实这是个很现实的问题，为了增加开发效率，开发人员有必要对变量进行管理。<img src ="http://www.cppblog.com/blueskiner/aggbug/185528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2012-07-29 09:56 <a href="http://www.cppblog.com/blueskiner/archive/2012/07/29/185528.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unix/Linux头文件说明</title><link>http://www.cppblog.com/blueskiner/archive/2012/07/29/185527.html</link><dc:creator>卡洛shll</dc:creator><author>卡洛shll</author><pubDate>Sun, 29 Jul 2012 01:45:00 GMT</pubDate><guid>http://www.cppblog.com/blueskiner/archive/2012/07/29/185527.html</guid><wfw:comment>http://www.cppblog.com/blueskiner/comments/185527.html</wfw:comment><comments>http://www.cppblog.com/blueskiner/archive/2012/07/29/185527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blueskiner/comments/commentRss/185527.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blueskiner/services/trackbacks/185527.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ISO C 标准头文件HeaderFreeBSD 5.2.1Linux 2.4.22Mac OS X 10.3Solaris 9Description&lt;assert.h&gt;&#8226;&#8226;&#8226;&#8226;verify prog...&nbsp;&nbsp;<a href='http://www.cppblog.com/blueskiner/archive/2012/07/29/185527.html'>阅读全文</a><img src ="http://www.cppblog.com/blueskiner/aggbug/185527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blueskiner/" target="_blank">卡洛shll</a> 2012-07-29 09:45 <a href="http://www.cppblog.com/blueskiner/archive/2012/07/29/185527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>