﻿<?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++博客-bird</title><link>http://www.cppblog.com/bird/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 09 Jun 2026 18:52:06 GMT</lastBuildDate><pubDate>Tue, 09 Jun 2026 18:52:06 GMT</pubDate><ttl>60</ttl><item><title>自定义C++流的分隔符</title><link>http://www.cppblog.com/bird/archive/2007/12/01/37603.html</link><dc:creator>csbird</dc:creator><author>csbird</author><pubDate>Sat, 01 Dec 2007 03:42:00 GMT</pubDate><guid>http://www.cppblog.com/bird/archive/2007/12/01/37603.html</guid><wfw:comment>http://www.cppblog.com/bird/comments/37603.html</wfw:comment><comments>http://www.cppblog.com/bird/archive/2007/12/01/37603.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/bird/comments/commentRss/37603.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bird/services/trackbacks/37603.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; C++输入流的默认分隔符是空格和回车。在某些场合，输入数据会以其他字符作为分隔符，如&#8216;，&#8217;，&#8216;；&#8217;等。通常我们可以将数据读入后再处理；STL则提供了一些方法使得我们可以在流这一层面上就进行过滤。<br>&nbsp;&nbsp;&nbsp; C++的流处理都是与locale（本地化）相关的，每个locale包含了如何处理数值（numeric）、时间和日期（time）、货币（monetary）、字符的分类和转换（ctype）等信息。STL将这样的每个类别称为facet。<br>&nbsp;&nbsp;&nbsp; 现在我们期望输入流能够将自定义的字符如&#8216;，&#8217;识别为空格，这属于字符分类的处理。可通过继承STL中的ctype&lt;&gt;来实现自定义的字符分类。代码如下：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">//</span><span style="color: #008000;">FilterCharacter.h</span><span style="color: #008000;"><br></span><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">locale</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;FilterCharacter&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;std::ctype</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">chars包含用户自定义的分隔字符</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;FilterCharacter(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;std::string</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;chars);<br><br></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;std::ctype_base::mask&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;getTable(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;std::string</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;chars);<br>};<br><br></span><span style="color: #008000;">//</span><span style="color: #008000;">FilterCharacter.cpp<br><br>//这里的true参数指明当FilterCharacter实例被销毁时，自动销毁getTable中生成的table<br>//也可以为false，表明当该FilterCharacter的引用计数为0时才销毁table<br></span><span style="color: #008000;"></span><span style="color: #000000;">FilterCharacter::FilterCharacter(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;std::string</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;chars)&nbsp;:&nbsp;std::ctype</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(getTable(chars),&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">)<br>{<br>}<br><br><br>std::ctype_base::mask&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;FilterCharacter::getTable(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;std::string</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;chars)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::ctype_base::mask</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;table&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;std::ctype_base::mask[std::ctype</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::table_size];<br>&nbsp;&nbsp;&nbsp;&nbsp;std::fill_n(table,&nbsp;std::ctype</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::table_size,&nbsp;std::ctype_base::mask());<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;chars.size();&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">将用户自定义的字符分类为空格</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;table[chars[i]]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;std::ctype_base::space;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;table;<br>}</span></div>
<br>有了这样一个ctype facet，将其安装到输入流的locale中，就可实现自定义分隔符。来看一个简单应用。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp; std::string&nbsp;name, age;<br><br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">将逗号和分号作为分隔符</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp; FilterCharacter&nbsp;filter(</span><span style="color: #000000;">"</span><span style="color: #000000;">;,</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">安装包含有自定义的的ctype的locale到输入流中</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cin.imbue(std::locale(std::locale(),&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">filter));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(std::cin&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;name&nbsp;</span><span style="color: #000000;"></span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;age</span><span style="color: #008000;"></span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">name:'</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;name&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">'\n</span><span style="color: #000000;">"</span><span style="color: #000000;"></span><span style="color: #000000;"></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;">age:&nbsp;'</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;age&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">'\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>}</span></div>
<br>参考资料：<br>《The C++ Standar Library》<br><br>       <img src ="http://www.cppblog.com/bird/aggbug/37603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bird/" target="_blank">csbird</a> 2007-12-01 11:42 <a href="http://www.cppblog.com/bird/archive/2007/12/01/37603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>