【C++】C++ 读取文件最后一行产生的问题

论坛 期权论坛     
匿名小用户   2019-10-20 17:58   138   0
<!-- 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>&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">string</span>&gt;</span> word;
    <span class="hljs-built_in">std</span>::<span class="hljs-stl_container"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">float</span>&gt;</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 &gt;&gt; word_tmp &gt;&gt; value_tmp;   <span class="hljs-comment">// &gt;&gt; 在添加头文件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> &lt;&lt;<span class="hljs-string">"--------------"</span>&lt;&lt;<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&lt;value.size(); i++)
    {
        <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"word:"</span> &lt;&lt; word[i] &lt;&lt;<span class="hljs-string">", value:"</span> &lt;&lt;  value[i] &lt;&lt;<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> &gt;&gt; word_tmp &gt;&gt; value_tmp;   <span class="hljs-comment">//&gt;&gt;在添加头文件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(
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:50
帖子:1079
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP