【问题标题】:Read file to istream replacing class variables读取文件到 istream 替换类变量
【发布时间】:2018-11-21 22:56:44
【问题描述】:

我了解如何实现重载的 ostream 运算符,但我对重载的 istream 运算符有点困惑。所有在线示例仅显示了一个简短的演示(即 is >> val; ),这对我的类变量和方法没有帮助。在我的主要内容中,我正在尝试读取文件并将指针内容替换为文件内容。我已经有一个工厂方法和读取方法,但我试图重载我的 istream 运算符来做同样的事情。 但是,虽然指针内容被替换了,但我仍然收到下面的 cerr 消息。我应该在我的 >> 函数中向 ifs 传递一些东西吗?

这是我的主要内容

int main() {

  // factory method instantiates all class variables
  Base *aa = Base::create(file);     // it works

  ifstream in(file2);
  if((in >> *aa).fail())             // Read file contents
    cerr << "Read failed" << '\n'; 

  cout << *aa;                       // prints vector contents
}

打印

// file     // file2      cout << *aa     SupposedToBe
555         111           Read Failed     111
555         222           111             222
555         333           222             333
                          333

到目前为止我所拥有的 (.cpp)

istream &operator>>(istream &ifs, Base &val) {

  string line;
  getline(ifs, line); // type of file

  if(line == "type1") 
    val.filetype = "type1";
  if(line == "type2")
    val.filetype = "type2";

  val.vec.clear();    // clear old vector
  vector<int> inner;  // inner vec to push onto main vec

  // read remaining contents
  while(getline(ifs, line)) {

    for(size_t i = 0; i < line.length(); i++) 
       inner.push_back(line[i]);

    val.vec.push_back(inner);
    inner.clear();
  }

  val.height = val.vec.size();
  val.width = val.vec[0].size();
  val.max = val.vec[height-1][width-1];

  return ifs;
}

我重载的 ostream 函数看起来与上面显示的有很大不同(即很多 os > value 时,我都会遇到各种编译器错误(即我尝试只执行 ifs >> val.image; ifs >> val.height; 等等,但我得到的只是编译器错误)。我应该将什么传递给 istream(在上面的函数中),所以上面的错误(下面的 main)不会显示。

.h 文件供参考

class Base 
{
  protected:
    std::vector<std::vector<int> > vec;
    std::string filetype;
    int width, height, max;
    Base() = default;
    Base &operator=(const Base &) = default;
  public:
    static Base* create(std::string filename);
    virtual ~Base();
    // read by derived class
    virtual void read(std::string filename) = 0;
    friend std::istream &operator>>(std::istream &, Base &);
    friend std::ostream &operator<<(std::ostream &, const Image &);
};

【问题讨论】:

  • Base *aa = Base::create(file); - 不要那样做 - 不需要使用指针。
  • 作为一个真正完整的例子,我们还需要您的输入文件。
  • 我添加了它。它在 main 下方。

标签: c++ istream


【解决方案1】:

使用

if((in >> *aa).fail())             // Read file contents
   cerr << "Read failed" << '\n';

是个问题。以您实现operator&gt;&gt;(std::istream &amp;, Base &amp;) 的方式,该逻辑每次都会失败。

函数中有一个循环

while(getline(ifs, line)) {
   ...
}

只有当没有从文件中读取内容或读取文件内容出错时,该循环才会中断。当该循环退出时,ifs.fail() 将始终为真。

您应该将 if 语句替换为:

in >> *aa;

如果您需要进行任何错误检查并打印相应的错误消息,则必须在 operator&gt;&gt;(std::istream &amp;, Base &amp;) 内完成。

更新,以回应 OP 的评论

确保istream 不会达到ifs.fail() 始终为true 的一种方法是提前了解预期内容。

如果文件中预期的行数是第一个输入,则可以读取所有数据并从函数返回,使得ifs.fail()false

示例输入:

type1
3
111
222
333

那么,oprator&gt;&gt;函数可以定义为:

std::stream& operator>>(std::istream& ifs, Base& val) 
{
   std::string line;
   if ( !getline(ifs, line) ) // type of file
   {
      // Problem reading. No point trying to read more.
      return ifs;
   }

   if(line == "type1") 
      val.filetype = "type1";
   if(line == "type2")
      val.filetype = "type2";

   // read remaining contents

   int numLines = 0;
   if ( !(ifs >> numLines) )
   {
      // Problem reading. No point trying to read more.
      return ifs;
   }

   val.vec.clear();    // clear old vector
   vector<int> inner;  // inner vec to push onto main vec

   for ( int n = 0; n < numLines; ++n )
   {
      if ( !getline(ifs, line))
      {
         // Problem reading. No point trying to read more.
         return ifs;
      }

      for(size_t i = 0; i < line.length(); i++) 
      {
         inner.push_back(line[i]);
      }

      val.vec.push_back(inner);
      inner.clear();
   }

   val.height = val.vec.size();
   val.width = val.vec[0].size();
   val.max = val.vec[height-1][width-1];

   return ifs;
}

【讨论】:

  • 有没有办法在我的 operator>> 函数中修复我的逻辑,使其不会失败?在 >> *aa;可以正常工作,但我需要使用您在回复中突出显示的 if 语句。
  • 是的。我脑海中的完整回复很长,我无法在几个小时内完成。
猜你喜欢
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 2022-11-17
  • 1970-01-01
  • 2013-09-14
  • 2013-03-26
  • 1970-01-01
相关资源
最近更新 更多