⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 item_29.html

📁 制作本书的目的是为了方便大家的阅读。转载时请保持本电子书的完整性。 前言、条款2、16、21、44根据从Addison-Wesley出版社下载的开放条款翻译。条款26、27、28、45根据从Sc
💻 HTML
字号:
<?xml version="1.0" encoding="gb2312"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>条款29:需要一个一个字符输入时考虑使用istreambuf_iterator</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><link href="css/all.css" rel="stylesheet" type="text/css" /><link rel="stylesheet" href="http://stl.winterxy.com/styles-site.css" type="text/css" /><link rel="alternate" type="application/rss+xml" title="RSS" href="http://stl.winterxy.com/index.rdf" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://stl.winterxy.com/rsd.xml" /></head><body><div id="banner"><h1><a href="http://stl.winterxy.com/" accesskey="1">Center of STL Study</a> </h1><span class="description">——最优秀的STL学习网站<script language="javascript" src="http://www.winterxy.com/cgi-bin/js/webstats.js"></script></span></div><h2>条款29:需要一个一个字符输入时考虑使用istreambuf_iterator</h2> <p>假设我们要把一个文本文件拷贝到一个字符串对象中。似乎可以用一种很有道理的方法完成:</p> <pre>ifstream inputFile(&quot;interestingData.txt&quot;);string fileData((istream_iterator&lt;char&gt;(inputFile)),		// 把inputFile读入			istream_iterator&lt;char&gt;());		// fileData;关于为什么							// 它不是很正确请看下文							// 关于这个语法的警告							// 参见<a href="item_06.html">条款6</a></pre> <p>很快你就会发现这种方法无法把文件中的空格拷贝到字符串中。那是因为istream_iterators使用operator&gt;&gt;函数来进行真的读取,而且operator&gt;&gt;函数在默认情况下忽略空格。</p> <p>假如你想保留空格,你要的做就是覆盖默认情况。只要清除输入流的skipws标志就行了:</p> <pre>ifstream inputFile(&quot;interestingData.txt&quot;);inputFile.unset(ios::skipws);				// 关闭inputFile的							// 忽略空格标志string fileData((istream_iterator&lt;char&gt;(inputFile)), istream_iterator&lt;char&gt;());</pre> <p>现在inputFile中的所有字符都拷贝到fileData中了。</p> <p>唉,你会发现它们的拷贝速度不像你想象的那么快。istream_iterators所依靠的operator&gt;&gt;函数进行的是格式化输入,这意味着每次你调用的时候它们都必须做大量工作。它们必须建立和销毁岗哨(sentry)对象(为每个operator&gt;&gt;调用进行建立和清除活动的特殊的iostream对象),它们必须检查可能影响它们行为的流标志(比如skipws),它们必须进行全面的读取错误检查,而且如果它们遇到问题,它们必须检查流的异常掩码来决定是否该抛出一个异常。如果进行格式化输入,那些都是重要的活动,但如果你需要的只是从输入流中抓取下一个字符,那就过度了。</p> <p>一个更高效的方法是使用STL最好的秘密武器之一:istreambuf_iterators。你可以像istream_iterator一样使用istreambuf_iterator,但istream_iterator&lt;char&gt;对象使用operator&gt;&gt;来从输入流中读取单个字符。istreambuf_iterator&lt;char&gt;对象进入流的缓冲区并直接读取下一个字符。(更明确地说,一个istreambuf_iterator&lt;char&gt; 对象从一个istream s中读取会调用s.rdbuf()-&gt;sgetc()来读s的下一个字符。)把我们的文件读取代码改为使用istreambuf_iterator相当简单,大多数Visual Basic程序员都可以在两次尝试内做对:</p> <pre>ifstream inputFile(&quot;interestingData.txt&quot;);string fileData((istreambuf_iterator&lt;char&gt;(inputFile)),			istreambuf_iterator&lt;char&gt;());</pre> <p>注意这里不需要“unset”skipws标志,istreambuf_iterator不忽略任何字符。它们只抓取流缓冲区的下一个字符。</p> <p>相对于istream_iterator,它们抓取得更快——在我进行的简单测试中能快40%,如果你的结果不同也不用惊奇。如果随时间流逝,速度优势不断增加也不必奇怪,因为istreambuf_iterator存在于STL的一个不常访问的角落,所以实现还没有花很多时间来优化。比如,在我用过的一个实现中,istreambuf_iterator在我的主要测试中只比istream_iterator快了大约5%。那样的实现显然还有很多余地来优化它们的istreambuf_iterator实现。如果你需要一个一个地读取流中的字符,你不需要格式化输入的威力,你关心的是它们花多少时间来读取流,和明显的性能提高相比,为每个迭代器多键入三个字符的代价是微弱的。对于无格式的一个一个字符输入,你总是应该考虑使用istreambuf_iterator。</p> <p>当你了解它之后,你也应该考虑把ostreambuf_iterator用于相应的无格式一个一个字符输出的作。它们没有了ostream_iterator的开销(和灵活性),所以它们通常也做得更好。</p> </body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -