C++ fstream对象作为引用传递,但它不会使

wwwo4jvm  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(134)

我想用.txt文件做很多事情,所以我想把它分解成函数。但是即使我通过引用传递文件流,我也不能编译程序。

#include "Executive.h"
    #include "Clip.h"
    #include <string>
    #include <iostream>
    #include <fstream>

    void Executive::readFile()
    {
        std::fstream streamer;
        streamer.open(m_file);
        if(streamer.is_open ())
        {
            findStart(streamer);

            for(int i = 0; i < 13; i++)
            {
                std::string temp;
                streamer >> temp;
            }

            for(int i = 0; i < 20; i++)
            {
                std::string temp;
                streamer >> temp;
                std::cout << temp << "  ";
                if(i == 10) {std::cout << "\n";}
            }

            streamer.close();
            return;
        }
        else
        { throw std::runtime_error("Could not read file!\n"); }
    }

    void findStart(const std::fstream& stream)
    {
        bool isStart = 0;

            while(!isStart)
            {
                std::string temp;
                stream >> temp;

                if(temp == "Sc/Tk")
                { isStart = 1; }
            }
    }
wrrgggsh

wrrgggsh1#

要解决这个问题,你可以在findStart函数的声明中删除const关键字。

TL;DR;

一般来说,如果你只想从文件中读取,请使用ifstream而不是fstream。
你的代码问题是stream >> temp;不与const fstream一起工作,因为operator >>已经声明如下

template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT, Traits>&
    operator>>( std::basic_istream<CharT, Traits>& is,
                std::basic_string<CharT, Traits, Allocator>& str );

正如你所看到的,operator>>没有任何const reference流对象的重载,所以你的代码是错误的,不能编译,如果你想知道为什么C++没有提供这个重载,你可以看到下面的实现例子

1540     {
1541       typedef basic_istream<_CharT, _Traits>            __istream_type;
1542       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
1543       typedef typename __istream_type::ios_base         __ios_base;
1544       typedef typename __istream_type::int_type         __int_type;
1545       typedef typename __string_type::size_type         __size_type;
1546
1547       __size_type __extracted = 0;
1548       const __size_type __n = __str.max_size();
1549       typename __ios_base::iostate __err = __ios_base::goodbit;
1550       typename __istream_type::sentry __cerb(__in, true);
1551       if (__cerb)
1552         {
1553           __try
1554             {
1555               __str.erase();
1556               const __int_type __idelim = _Traits::to_int_type(__delim);
1557               const __int_type __eof = _Traits::eof();
1558               __int_type __c = __in.rdbuf()->sgetc();
1559
1560               while (__extracted < __n
1561                      && !_Traits::eq_int_type(__c, __eof)
1562                      && !_Traits::eq_int_type(__c, __idelim))
1563                 {
1564                   __str += _Traits::to_char_type(__c);
1565                   ++__extracted;
1566                   __c = __in.rdbuf()->snextc();
1567                 }
1568
1569               if (_Traits::eq_int_type(__c, __eof))
1570                 __err |= __ios_base::eofbit;
1571               else if (_Traits::eq_int_type(__c, __idelim))
1572                 {
1573                   ++__extracted;
1574                   __in.rdbuf()->sbumpc();
1575                 }
1576               else
1577                 __err |= __ios_base::failbit;
1578             }
1579           __catch(__cxxabiv1::__forced_unwind&)
1580             {
1581               __in._M_setstate(__ios_base::badbit);
1582               __throw_exception_again;
1583             }
1584           __catch(...)
1585             {
1586               // _GLIBCXX_RESOLVE_LIB_DEFECTS
1587               // 91. Description of operator>> and getline() for string<>
1588               // might cause endless loop
1589               __in._M_setstate(__ios_base::badbit);
1590             }
1591         }
1592       if (!__extracted)
1593         __err |= __ios_base::failbit;
1594       if (__err)
1595         __in.setstate(__err);
1596       return __in;
1597     }

正如你在上面的例子中所看到的,为了实现operator>>,我们需要改变流的状态来知道(并保存)最后一次读取的位置。

相关问题