<!-- flowchart 箭头图标 勿删 -->
<svg style="display: none;">
<path d="M5,0 0,2.5 5,5z" id="raphael-marker-block" stroke-linecap="round" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<blockquote>
<p>之前写了一个读取文件的代码,发现每次读取的行数都比实际多一行。文档是一行行的数据,最后确实有一个空行,这是因为输出这个文档的时候,每一行都有一个换行符,所以必然导致最后一行有一个空行。这是一个非常普遍的现象,本文就研究一下如何正确的读取文本。</p>
</blockquote>
<p>首先,我们的测试文档如下,最后的点表示这是一个空行,实际中并没有。</p>
<pre class="blockcode"><code class="hljs cs"><span class="hljs-keyword">new</span> <span class="hljs-number">1.23</span>
fan <span class="hljs-number">2</span>
jin <span class="hljs-number">4.444</span>
ge <span class="hljs-number">0.10203</span>
.</code></pre>
<h3 id="1-使用eof来判断">1. 使用eof来判断</h3>
<p>先看一段错误的代码</p>
<pre class="blockcode"><code class="hljs cpp"><span class="hljs-keyword">int</span> read_1()
{
<span class="hljs-built_in">std</span>::ifstream file(<span class="hljs-string">"test.txt"</span>);
<span class="hljs-built_in">std</span>::<span class="hljs-stl_container"><span class="hljs-built_in">vector</span><<span class="hljs-built_in">std</span>::<span class="hljs-built_in">string</span>></span> word;
<span class="hljs-built_in">std</span>::<span class="hljs-stl_container"><span class="hljs-built_in">vector</span><<span class="hljs-keyword">float</span>></span> value;
<span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
<span class="hljs-comment">// A word and a double value were both read successfully</span>
<span class="hljs-keyword">float</span> value_tmp;
<span class="hljs-built_in">std</span>::<span class="hljs-built_in">string</span> word_tmp;
file >> word_tmp >> value_tmp; <span class="hljs-comment">// >> 在添加头文件sstream之后可以使用,否则会报错</span>
value.push_back(value_tmp);
word.push_back(word_tmp);
<span class="hljs-keyword">if</span>( file.eof() )
<span class="hljs-keyword">break</span>;
}
<span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> <<<span class="hljs-string">"--------------"</span><<<span class="hljs-built_in">std</span>::endl;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i<value.size(); i++)
{
<span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> << <span class="hljs-string">"word:"</span> << word[i] <<<span class="hljs-string">", value:"</span> << value[i] <<<span class="hljs-built_in">std</span>::endl;
}
file.close();
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}</code></pre>
<p>或者这么写也一样</p>
<pre class="blockcode"><code class="hljs mel"><span class="hljs-keyword">while</span> (!<span class="hljs-keyword">file</span>.eof()) {
<span class="hljs-comment">// A word and a double value were both read successfully</span>
<span class="hljs-keyword">float</span> value_tmp;
std::<span class="hljs-keyword">string</span> word_tmp;
<span class="hljs-keyword">file</span> >> word_tmp >> value_tmp; <span class="hljs-comment">//>>在添加头文件sstream之后可以使用,否则会报错</span>
value.push_back(value_tmp);
word.push_back(word_tmp);
}</code></pre>
<p>输出结果</p>
<pre class="blockcode"><code class="hljs livecodeserver"><span class="hljs-comment">--------------</span>
<span class="hljs-built_in">word</span>:<span class="hljs-built_in">new</span>, <span class="hljs-built_in">value</span>:<span class="hljs-number">1.23</span>
<span class="hljs-built_in">word</span>:fan, <span class="hljs-built_in">value</span>:<span class="hljs-number">2</span>
<span class="hljs-built_in">word</span>:jin, <span class="hljs-built_in">value</span>:<span class="hljs-number">4.444</span>
<span class="hljs-built_in">word</span>:ge, <span class="hljs-built_in">value</span>:<span class="hljs-number">0.10203</span>
<span class="hljs-built_in">word</span>:, <span class="hljs-built_in">value</span>:<span class="hljs-number">0.10203</span></code></pre>
<p>可以看到多了一行。</p>
<blockquote>
<p><strong>分析</strong>:eof从字面意思来看,当然是end of file,用于表明当前已经到了文件末尾,不能再读了。 <br>
但这里有一个很迷惑的陷阱:只要遇到结束符,流就会将状态置为EOF,而不管置位前的操作是否成功。 <br>
例如,使用getline函数读取文件的最后一行,如果这一行是因为遇到了EOF而结束的,那么getline操作是成功的,但eof还是会置位。</p>
</blockquote>
<h3 id="2-while循环中输出">2. while循环中输出</h3>
<p>代码如下:</p>
<pre class="blockcode"><code class="hljs cpp"><span class="hljs-keyword">int</span> read_2()
{
<span class="hljs-built_in">std</span>::ifstream file( |
|