??xml version="1.0" encoding="utf-8" standalone="yes"?>
find命o是一个无处不在命令,是linux中最有用的命令之一。find命o用于Q在一个目录(及子目录Q中搜烦文gQ你可以指定一些匹配条Ӟ如按文g名、文件类型、用Lx旉x找文件。下面就通过实例来体验下find命o的强大?/p>
man文档中给出的find命o的一般Ş式ؓQ?/p>
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
其实[-H] [-L] [-P] [-D debugopts] [-Olevel]q几个选项q不常用Q至在我的日常工作中,没有用到q)Q上面的find命o的常用Ş式可以简化ؓQ?/p>
find [path...] [expression]
也有hȝfind命o的结构:
find start_directory test
options
criteria_to_match
action_to_perform_on_results
在用find命o?exec选项处理匚w到的文gӞ find命o所有匹配到的文件一起传递给exec执行。但有些pȝ对能够传递给exec的命令长度有限制Q这样在find命oq行几分钟之后,׃出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这是xargs命o的用处所在,特别是与find命o一起用?/p>
find命o把匹配到的文件传递给xargs命oQ而xargs命o每次只获取一部分文g而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文gQ然后是下一批,q如此l下厅R?/p>
在有些系l中Q?exec选项会ؓ处理每一个匹配到的文件而发起一个相应的q程Qƈ非将匚w到的文g全部作ؓ参数一ơ执行;q样在有些情况下׃出现q程q多Q系l性能下降的问题,因而效率不高;
而用xargs命o则只有一个进E。另外,在用xargs命oӞI竟是一ơ获取所有的参数Q还是分批取得参敎ͼ以及每一ơ获取参数的数目都会Ҏ该命令的选项及系l内怸相应的可调参数来定?/font>
来看看xargs命o是如何同find命o一起用的Qƈl出一些例子?/p>
find . -type f -print | xargs file 查找pȝ中的每一个普通文Ӟ然后使用xargs命o来测试它们分别属于哪cL?/p>
find / -name "core" -print | xargs echo "" >/tmp/core.log 在整个系l中查找内存信息转储文g(core dump) Q然后把l果保存?tmp/core.log 文g中:
find . -type f -print | xargs grep "hostname" 用grep命o在所有的普通文件中搜烦hostnameq个?/p>
find ./ -mtime +3 -print|xargs rm -f –r 删除3天以前的所有东?Qfind . -ctime +3 -exec rm -rf {} \;Q?/p>
find ./ -size 0 | xargs rm -f & 删除文g大小为零的文?/p>
find命o配合使用exec和xargs可以使用户对所匚w到的文g执行几乎所有的命o?/p>
grep (global search regular expression(RE) and print out the line,全面搜烦正则表达式ƈ把行打印出来)是一U强大的文本搜烦工具Q它能用正则表辑ּ搜烦文本Qƈ把匹配的行打印出来?/p>
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
grep命o用于搜烦由Pattern参数指定的模式,q将每个匚w的行写入标准输出中。这些模式是h限定的正则表辑ּQ它们用ed或egrep命o样式。如果在File参数中指定了多个名称Qgrep命o显C包含匹配行的文件的名称。对 shell 有特D含义的字符 ($, *, [, |, ^, (, ), \ ) 出现?Pattern参数中时必须带双引号。如?Pattern参数不是单字W串Q通常必须用单引号整个模式括h。在诸如 [a-z], 之类的表辑ּ中,-Q减Pcml 可根据当前正在整理的序列来指定一个范围。整理序列可以定义等LcM供在字符范围中用。如果未指定M文gQgrep会假定ؓ标准输入?/p>
^ 锚定行的开?如:'^grep'匚w所有以grep开头的行?/p>
$ 锚定行的l束 如:'grep$'匚w所有以grepl尾的行?/p>
. 匚w一个非换行W的字符 如:'gr.p'匚wgr后接一个Q意字W,然后是p?/p>
* 匚w零个或多个先前字W?如:'*grep'匚w所有一个或多个I格后紧跟grep的行?font size="3"> .*一L代表L字符?/p>
[] 匚w一个指定范围内的字W,?[Gg]rep'匚wGrep和grep?/p>
[^] 匚w一个不在指定范围内的字W,如:'[^A-FH-Z]rep'匚w不包含A-R和T-Z的一个字母开_紧跟rep的行?/p>
\(..\) 标记匚w字符Q如Q?\(love\)'Qlove被标Cؓ1?/p>
\< 锚定单词的开始,如:'\<grep'匚w包含以grep开头的单词的行?/p>
\> 锚定单词的结束,?grep\>'匚w包含以grepl尾的单词的行?/p>
x\{m\} q箋重复字符xQmơ,如:'o\{5\}'匚w包含q箋5个o的行?/p>
x\{m,\} q箋重复字符x,臛_mơ,如:'o\{5,\}'匚w臛_q箋?个o的行?/p>
x\{m,n\} q箋重复字符xQ至mơ,不多于nơ,如:'o\{5,10\}'匚wq箋5--10个o的行?/p>
\w 匚w一个文字和数字字符Q也是[A-Za-z0-9]Q如Q?G\w*p'匚w以G后跟零个或多个文字或数字字符Q然后是p?/p>
\W w的反|Ş式,匚w一个非单词字符Q如点号句号{。\W*则可匚w多个?/p>
\b 单词锁定W,? '\bgrep\b'只匹配grepQ即只能是grepq个单词Q两边均为空根{?/p>
-?
同时昄匚w行上下的Q行Q如Qgrep -2 pattern filename同时昄匚w行的上下2行?/p>
-bQ?-byte-offset
打印匚w行前面打印该行所在的块号码?/p>
-c,--count
只打印匹配的行数Q不昄匚w的内宏V?/p>
-f FileQ?-file=File
从文件中提取模板。空文g中包?个模板,所以什么都不匹配?/p>
-hQ?-no-filename
当搜索多个文件时Q不昄匚w文g名前~?/p>
-iQ?-ignore-case
忽略大小写差别?/p>
-qQ?-quiet
取消昄Q只q回退出状态?则表C找C匚w的行?/p>
-lQ?-files-with-matches
打印匚w模板的文件清单?/p>
-LQ?-files-without-match
打印不匹配模板的文g清单?/p>
-nQ?-line-number
在匹配的行前面打印行受?/p>
-sQ?-silent
不显C关于不存在或者无法读取文件的错误信息?/p>
-vQ?-revert-match
反检索,只显CZ匚w的行?/p>
-wQ?-word-regexp
如果被\<和\>引用Q就把表辑ּ做ؓ一个单词搜索?/p>
-VQ?-version
昄软g版本信息?/p>
=====
ls -l | grep '^a' 通过道qols -l输出的内容,只显CZa开头的行?/p>
grep 'test' d* 昄所有以d开头的文g中包含test的行?/p>
grep 'test' aa bb cc 昄在aaQbbQcc文g中匹配test的行?/p>
grep '[a-z]' aa 昄所有包含每个字W串臛_?个连l小写字W的字符串的行?/p>
grep 'w(es)t.*' aa 如果west被匹配,则esp存储到内存中Qƈ标记?Q然后搜索Q意个字符(.*)Q这些字W后面紧跟着另外一个es()Q找到就昄该行。如果用egrep或grep -EQ就不用""可行{义,直接写成'w(es)t.*'可以了?/p>
grep -i pattern files Q不区分大小写地搜烦。默认情况区分大写
grep -l pattern files Q只列出匚w的文件名Q?/p>
grep -L pattern files Q列Z匚w的文件名Q?/p>
grep -w pattern files Q只匚w整个单词Q而不是字W串的一部分(如匹配‘magic’,而不是‘magical?Q?/p>
grep -C number pattern files Q匹配的上下文分别显C[number]行,
grep pattern1 | pattern2 files Q显C匹?pattern1 ?pattern2 的行Q?/p>
grep pattern1 files | grep pattern2 Q显C既匚w pattern1 又匹?pattern2 的行?/p>
参考文献:
——借此感谢在实习公司同事们l与的帮助,
特别是Jay、Jeff?/p>
Map是标?strong>兌式容?/strong>Q?em>associative containerQ之一Q一个map是一个键值对序列Q即Qkey ,valueQ对。它提供Zkey?strong>快?/strong>索能力,在一个map中key值是唯一的。map提供双向q代器,x从前往后的QiteratorQ,也有从后往前的Qreverse_iteratorQ?/p>
map要求能对keyq行<操作Q且保持按key值递增有序Q因此map上的q代器也是递增有序的。如果对于元素ƈ不需要保持有序,可以使用hash_map?/p>
map中key值是唯一的,如果马匹中已存在一个键值对(늧,密码):("skynet",407574364)Q而我们还x入一个键值对("skynet",472687789)则会报错Q?span style="color: #ff0000;">不是报错Q准的说是Q返回插入不成功Q?/span>Q。而我们又的确惌样做Q即一个键对应多个|q运的是multimap可是实现q个功能?/p>
下面我们用实例来深入介绍map?em>multimapQ主要内容如下:
有一个服务器managerl护着接入服务器的client信息Q包括clinetId、scanRate、socketAddr{等。我们定义一个结构体保存scanRate、socketAddr信息。如下:
typedef int clientId; typedef struct{ int scanRate; string socketAddr; }clientInfo;
我们用map保存q些信息QclientId为键keyQclientInfo为倹{这h们可以通过clientId快速检索到client的相关信息,我们可以q样定义Q?/p>
map<clientId,clientInfo> clientMap;
q样我们定义了一个clientMapQ如果我们要定义多个q样的mapQ需要多ơ写map<clientId,clientInfo> 变量名。ؓ了避免这h况,我们通常为map<clientId,clientInfo>定义个别名,如:
typedef map<clientId,clientInfo> clientEdp; clientEdp clientMap;
之后我们可以像定义clientMap一样定义map<clientId,clientInfo>对象Q这L好处q有Q如果我们需要修改map的定义,只需要在一处修改即可,避免修改不彻底造成的不一致现象?/p>
我们q就完成了需要的map的定义,如果不定义或没有在它上面的操作的话,像定义c而没有方法一P意义不大或毫无意义。幸q的是,STL提供了这些常用操作:排序Q注Qmap是不能也不要排序的,因ؓmap本n已经排好序了Q、打印、提取子部分、移除元素、添加元素、查扑֯象,像数据库的增删Ҏ操作Q现在我们详l介l这些操作,q步引入hash_map?em>multimap?/p>
兌数组Q?em>associative arrayQ是最有用的用户定义类型之一Q经常内|在语言中用于文本处理等。一个关联数l通常也称为mapQ有时也U字典(dictionaryQ,保存一对倹{第一个值称为key、第二个UCؓ映射值mapped-value?/p>
标准map是定义在std命名I间中的一个模板,q表CZؓ<map>。它首先定义了一l标准类型名字:
template<class Key,class T,class Cmp=less<key>, class A=allocator<pair<const Key,T>> class std::map { public: //types typedef Key key_type; typedef T mapped_type; typedef pair<const Key,T> value_type; typedef Cmp key_compare; typedef A allocator_type; typedef typename A::reference reference; typedef typename A::const_reference const_reference; typedef implementation_define1 iterator; typedef implementation_define2 const_iterator; typedef typename A::size_type size_type; typedef typename A::difference_type difference_type; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; //... }
注意Qmap的value_type是一?key,value)对,映射值的被认为是mapped_type。因此,一个map是一个pair<const Key,mapped_type>元素的序列。从const Key可以看出Qmap中键key是不可修改的?/p>
不得不提的是map定义中Cmp和A都是可选项。Cmp是定义在元素之间的比较方法,默认?lt;操作QA即allocator用来分配?strong>释放map总键值对所需使用的内存,没有指定的话即默认用的是STL提供的,也可以自定义allocator来管理内存的使用。多数情况,我们不指定这两个选项而用默认|q样我们定义map像下面q样Q?/p>
map<int,clientInfo> clientMap;
Cmp和A都缺省?通常Q实际的q代器是实现定义的,因ؓmap很像使用了树的Ş式,q些q代器通常提供树遍历的某种形式。逆向q代器是使用标准的reverse_iterator模板构造的?/p>
map提供惯常的返回P代器的一l函敎ͼ如下所C:
template<class Key,class T,class Cmp=less<key>, class A=allocator<pair<const Key,T>> class std::map { public: //... //iterators iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; reverse_iterator rbegin(); const_reverse_iterator rbegin() const; reverse_iterator rend(); const_reverse_iterator rend() const; //... }
map上的q代器是pair<const Key,mapped_type>元素序列上简单的q代。例如,我们可能需要打印出所有的客户端信息,像下面的E序q样。ؓ了实现这个,我们首先向《例子引入》中定义的clientEdp中插入数据,然后打印出来Q?/p>
#include<iostream> #include<map> #include<string> using namespace std; typedef int clientId; typedef struct{ int scanRate; string socketAddr; }clientInfo; int main(int argc,char** argv) { typedef map<clientId,clientInfo> clientEdp; typedef map<clientId,clientInfo>::const_iterator iterator; clientEdp clients; clientInfo client[100]; char str[10]; string strAddr("socket addr client "); for(int i=0;i<100;i++) { client[i].scanRate=i+1; //convert int to char* itoa(i+1,str,10); //concatenate strAddr and str client[i].socketAddr=strAddr+str; cout<<client[i].socketAddr<<endl; clients.insert( make_pair(i+1,client[i])); } delete str; for(iterator i=clients.begin();i!=clients.end();i++) { cout<<"clientId:"<<i->first<<endl; cout<<"scanRate:"<<i->second.scanRate<<endl; cout<<"socketAddr:"<<i->second.socketAddr<<endl; cout<<endl; } }
一个mapq代器以key升序方式表示元素Q因此客L信息以cliendId升序的方式输出。运行结果可以证明这一点,q行l果如下所C:
?、程序运行结?/p>
我们以first引用键值对的keyQ以second引用mapped valueQ且不用key和mapped value是什么类型。其实pair在std的模板中是这样定义的Q?/p>
template <class T1,class T2>struct std::pair{ typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair():first(T1()),second(T2()){} pair(const T1& x,const T2& y):first(x),second(y){} template<class U,class V> pair(const pair<U,V>& p):first(p.first),second(p.second){} }
即map中,key是键值对的第一个元素且mapped value是第二个元素。pair的定义可以在<utility>中找刎ͼpair提供了一个方法方便创建键值对Q?/p>
template <class T1,class T2>pair<T1,T2> std::make_pair(const T1& t1,const T2& t2) { return pair<T1,T2>(t1,t2); }
上面的例子中我们qCq个Ҏ来创?clientId,clientInfo)对,q作为Insert()Ҏ的参数。每个pair默认初始化每个元素的gؓ对应cd的默认倹{?/p>
mapcL常提供了构造函数和析构函数Q如下所C:
template<class Key,class T,class Cmp=less<key>, class A=allocator<pair<const Key,T>> class std::map { //... //construct/copy/destroy explicit map(const Cmp&=Cmp(),const A&=A()); template<class In>map(In first,In last, const Com&=Cmp(),const A&=A()); map(const map&); ~map(); map& operator=(const map&); //... }
复制一个容器意味着为它的每个元素分配空_q拷贝每个元素倹{这样做是性能开销是很大的Q应该仅当需要的时候才q样做?strong>因此Qmap传的是引?/strong>?/p>
前面我们已经说过Q如果map中仅定义了一些key、mapped valuecd的信息而没有操作方法,如定义个仅有字D늚cL义不大甚x无意义。由此可见map中定义操作方法非帔R要!前面的例子我们就用到了不方法,如返回P代器的方法begin()、end()Q键值对插入Ҏinsert()。下面我们对map中的操作Ҏ做个全面的介l:
template<class Key,class T,class Cmp=less<key>, class A=allocator<pair<const Key,T>> class std::map { //... //map operations //find element with key k iterator find(const key_type& k); const_iterator find(const key_type& k) const; //find number of elements with key k size_type count() const; //find first element with key k iterator lower_bound(const key_type& k); const_iterator lower_bound(const key_type& k) const; //find first element with key greater than k iterator upper_bound(const key_type& k); const_iterator upper_bound(const key_type& k) const; //insert pair(key,value) pair<iterator,bool>insert(const value_type& val); iterator insert(iterator pos,const value_type& val); template<class In>void insert(In first,In last); //erase element void erase(iterator pos); size_type erase(const key_type& k); void erase(iterator first,iterator last); void clear(); //number os elements size_type size() const; //size of largest possible map size_type max_size() const; bool empty() const{return size()==0;} void swap(map&); //... }
上面q些Ҏ基本都能思义QPS.由此可见Q命名有多重要,我们qx要养成好的命名习惯,当然注释也必不可!Q。虽然已l非常清楚了了,但我q是惌解一下以消除不惜要的误解和更好地应用q些Ҏ?/p>
#include<iostream> #include<map> #include<string> using namespace std; typedef int clientId; typedef struct{ int scanRate; string socketAddr; }clientInfo; int main(int argc,char** argv) { typedef map<clientId,clientInfo> clientEdp; typedef map<clientId,clientInfo>::const_iterator iterator; clientEdp clients; clientInfo client[100]; char* str=new char[10]; string strAddr("socket addr client "); for(int i=0;i<100;i++) { client[i].scanRate=i+1; //convert int to char* itoa(i+1,str,10); //concatenate strAddr and str client[i].socketAddr=strAddr+str; clients.insert( make_pair(i+1,client[i])); } delete str; clientId id=10; iterator i=clients.find(id); if(i!=clients.end()){ cout<<"clientId: "<<id <<" exists in clients"<<endl; } else{ cout<<"clientId: "<<id <<" doesn't exist in clients"<<endl; } }
#include<iostream> #include<map> #include<string> using namespace std; typedef int clientId; typedef struct{ int scanRate; string socketAddr; }clientInfo; int main(int argc,char** argv) { typedef map<clientId,clientInfo> clientEdp; typedef map<clientId,clientInfo>::const_iterator iterator; clientEdp clients; clientId id=110; clientInfo cltInfo; cltInfo.scanRate=10; cltInfo.socketAddr="110"; pair<clientId,clientInfo> p110(id,cltInfo); pair<iterator,bool> p=clients.insert(p110); if(p.second){ cout<<"insert success!"<<endl; } else{ cout<<"insert failed!"<<endl; } //i points to clients[110]; iterator i=p.first; cout<<i->first<<endl; cout<<i->second.scanRate<<endl; cout<<i->second.socketAddr<<endl; }
上面我们看出Q这里我们插入键值对是首先声明一个键值对pair<clientId,clientInfo> p110(id,cltInfo); 然后再插入,q个我们之前make_pairҎ不一Pmake_pairҎ用的比较多?/p>
前面我们介绍了利用map的插入方法insert()Q声明键值对pair或make_pair生成键值对然后我们可以L的将键值对插入map中。其实mapq提供了更方便的插入操作利用下标QsubscriptingQ[]Q操作,如下Q?/p>
clientInfo cltInfo; cltInfo.scanRate=10; cltInfo.socketAddr="110"; clients[110]=cltInfo;
q样我们可以简单地键值对插入到map中了。下标操作在map中式q样定义的:
template<class Key,class T,class Cmp=less<key>, class A=allocator<pair<const Key,T>> class std::map { //... //access element with key k mapped_type& operator[](const key_type& k); //... }
我们来分析一下应用[]操作Q插入键值对的过E:查键k是否已经在map里。如果不Q就d上,以v作ؓ它的对应倹{如果k已经在map里,它的兌D更新成v。这里首先,查找110不在map中则创徏一个键?10的键值对Qƈ映D为默认|q里scanRate?QsocketAddr为空Q然后将映射D为cltInfo?如果110在map中已l存在的话,则只是更C110为键的映倹{?/p>
从上面的分析可知Q如果大量这h入数据,会严重媄响效率!如果你考虑效率问题Q请使用insert操作。insertҎQ节省了三次函数调用Q一个徏立时的默认映射值的对象Q一个销毁那个时的对象和一个对映射值的赋值操作?/p>
Note1Q?/strong>如果k已经存在map中,[]效率反而比insert的效率高Q而且更美观!如果能够兼顾q两者那岂不是很妙Q其实我们重写map中的[]操作Q首先判断k是否已经在map中,如果没有则调用insert操作Q否则调用内|的[]操作。如下列代码Q?/p>
Note2Q?/strong>我们视乎q忽略了一点,如果映射值mapped value的类型没有默认|怎么办?q种情况请勿使用[]操作插入?/p>
通过[]操作不仅仅是插入键值对Q我们也可以通过键key索出映射值mapped value。而且我们利用[]操作可以L地统计信息,如有q样q样一些键值对Qbook-nameQcountQ对Q?/p>
(book1,1)?book2,2)?book1,2)?book3,1)?book3,5) 我们计算每种book的数量d。我们可以这样做Q将它们d一个map<string,int>Q?/p>
l果如下所C:Q注意按住ctrl+z键结束输入) ?、程序运行结?/p>
前面介绍了mapQ可以说已经非常清晰了。如果允许clientId重复的话Qmap无能ؓ力了Q这时候就得multimap上场了!multimap允许键key重复Q即一个键对应多个映射倹{?/strong>其实除此之外Qmultimap跟map是很像的Q我们接下来在map的基上介lmultimap?/p>
multimap在std中的定义跟map一样只是类名ؓmultimapQmultimap几乎有map的所有方法和cd定义?/p>
假设我们惛_出键为key的所有映|我们可以q样做: Q说明:实际上,一般是不允许clientId重复的,q里只是Z举例。)q样是不是感觉很丑呢Q事实上Q我们可以更单的q样Q?/p>
map是一cd联式容器。它的特Ҏ增加和删除节点对q代器的影响很小Q除了那个操作节点,对其他的节点都没有什么媄响。对于P代器来说Q可以修改实|而不能修改key? map的功能: 展望Q本文不知不觉写了不字了,但仍未深入涉及到map定义的第3个和W?个参敎ͼ使用的都是默认倹{?/p>
template<class Key,class T,class Cmp=less<key>, 感兴者,h扄兌料or下面留言希望看到单独开介lmapW?个和W?个参数。您的支持,我的动力QPSQ在此文的原因,在与公司做项目用CmapҎȝ出来与大家共享,不过在进行个人ȝq程中,隑օ会有疏漏或不当之处,请不吝指出?/p>
?】《The C++ Programming Language (Special Edition)?/p>
?】《Effective STL?/p>//////////////////////////////////////////////
///@param MapType-map的类型参?
///@param KeyArgType-键的cd参数
///@param ValueArgtype-映射值的cd参数
///@return q代器,指向键ؓk的键值对
//////////////////////////////////////////////
template<typename MapType,
typename KeyArgType,
typename ValueArgtype>
typename MapType::iterator
efficientAddOrUpdate(MapType& m,
const KeyArgType& k,
const ValueArgtype& v)
{
typename MapType::iterator Ib = m.lower_bound(k);
if(Ib != m.end()&&!(m.key_comp()(k,Ib->first))) {
//key已经存在于map中做更新操作
Ib->second = v;
return Ib;
}
else{
//key不存在map中做插入操作
typedef typename MapType::value_type MVT;
return m.insert(Ib, MVT(k, v));
}
}
7、[]不仅插入
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(int argc,char** argv)
{
map<string,int> bookMap;
string book;
int count;
int total=0;
while(cin>>book>>count)
bookMap[book]+=count;
map<string,int>::iterator i;
for(i=bookMap.begin();i!=bookMap.end();i++)
{
total+=i->second;
cout<<i->first<<'\t'<<i->second<<endl;
}
cout<<"total count:"<<total<<endl;
}
8、multimap
pair<iterator,iterator> equal_range(const key_type& k);
pair<const_iterator,const_iterator>
equal_range(const key_type& k) const;
//find first element with key k
iterator lower_bound(const key_type& k);
const_iterator lower_bound(const key_type& k) const;
//find first element with key greater than k
iterator upper_bound(const key_type& k);
const_iterator upper_bound(const key_type& k) const;
#include<iostream>
#include<map>
#include<string>
using namespace std;
typedef int clientId;
typedef struct{
int scanRate;
string socketAddr;
}clientInfo;
int main(int argc,char** argv)
{
typedef multimap<clientId,clientInfo> clientEdp;
typedef multimap<clientId,clientInfo>::const_iterator iterator;
clientEdp clients;
clientInfo client[20];
char* str=new char[10];
string strAddr("socket addr client ");
for(int i=0;i<10;i++)
{
client[i].scanRate=i+1;
//convert int to char*
itoa(i+1,str,10);
//concatenate strAddr and str
client[i].socketAddr=strAddr+str;
clients.insert(
make_pair(10,client[i]));
}
for(int i=10;i<20;i++)
{
client[i].scanRate=i+1;
//convert int to char*
itoa(i+1,str,10);
//concatenate strAddr and str
client[i].socketAddr=strAddr+str;
clients.insert(
make_pair(i+1,client[i]));
}
delete str,strAddr;
//find elements with key 10
iterator lb=clients.lower_bound(10);
iterator ub=clients.upper_bound(10);
for(iterator i=lb;i!=ub;i++)
{
cout<<"clientId:"<<i->first<<endl;
cout<<"scanRate:"<<i->second.scanRate<<endl;
cout<<"socketAddr:"<<i->second.socketAddr<<endl;
cout<<endl;
}
}
//find elements with key 10
pair<iterator,iterator> p=clients.equal_range(10);
for(iterator i=p.first;i!=p.second;i++)
{
cout<<"clientId:"<<i->first<<endl;
cout<<"scanRate:"<<i->second.scanRate<<endl;
cout<<"socketAddr:"<<i->second.socketAddr<<endl;
cout<<endl;
}
ȝ
class A=allocator<pair<const Key,T>>参考文献: