2011-06-16 73 views
1

在我最近的question之後,我試圖實現我自己設計的例子。
我有一個基本的結構,但即使閱讀this,這可能是我見過的最好的教程,我仍然很困惑。我想我也許應該轉換成Chapter._text流和增值運營商做類似試圖實現一個沒有明確容器的迭代器

string p = ""; 
string line; 
while (getline(stream, line)) { 
    p += line; 
} 
return *p; 

,但我不知道要使用其中的「樣板」的typedef是如何把所有這些東西一起。感謝很多的幫助

#include <stdio.h> 
#include <stdlib.h> 
#include <vector> 
#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

class Paragraph { 
public: 
    string _text; 

    Paragraph (string text) { 
    _text = text; 
    } 
}; 

class Chapter { 
public: 
    string _text; 

    /* // I guess here I should do something like: 
    class Iterator : public iterator<input_iterator_tag, Paragraph> { 

    } 
    // OR should I be somehow delegating from istream_iterator ? */ 

    Chapter (string txt_file) { 
    string line; 

    ifstream infile(txt_file.c_str()); 
    if (!infile.is_open()) { 
     cout << "Error opening file " << txt_file << endl; 
     exit(0); 
    } 
    while (getline(infile, line)) { 
     _text += (line + "\n"); 
    } 
    } 

}; 

int main(int argc, char** argv) { 
    Chapter c(argv[1]); 

    // want to do something like: 
    // for (<Paragraph>::iterator pIt = c.begin(); pIt != c.end(); pIt++) { 
    // Paragraph p(*pIt); 
    // // Do something interesting with p 
    // } 

    return 0; 
} 
+0

'Chapter :: Iterator'應該如何移動? 'Chapter'類中的唯一數據是成員'_text',它存儲輸入文件_sans_行尾的_entire_內容。這個主意是什麼? – 2011-06-16 01:27:49

+0

謝謝,剛剛糾正了行結束。 – confusedCoder 2011-06-16 02:07:30

+0

所以...爲什麼不把整個文件讀入內存? – 2011-06-16 02:12:12

回答

1

當你沒有一個章節加載在同一時間(僅僅一個段落)計劃,和你的段落是空的,我認爲這可能與單paragraph_iterator類

來做得最好
class paragraph_iterator : 
public std::iterator<std::input_iterator_tag, std::string> 
{ 
    std::shared_ptr<std::ifstream> _infile; //current file 
    std::string _text; //current paragraph 
    paragraph_iterator(const paragraph_iterator &b); //not defined, so no copy 
    paragraph_iterator &operator=(const paragraph_iterator &b); //not defined, so no copy 
    // don't allow copies, because streams aren't copiable. 
    // make sure to always pass by reference 
    // unfortunately, this means no stl algorithms either 

public: 
    paragraph_iterator(string txt_file) :_infile(txt_file.c_str()) { 
     if (!infile.is_open()) 
      throw std::exception("Error opening file "); 
     std::getline(_infile, _text); 
    } 
    paragraph_iterator() {} 
    paragraph_iterator &operator++() { 
     std::getline(_infile, _text); 
     return *this; 
    } 
    // normally you'd want operator++(int) as well, but that requires making a copy 
    // and std::ifstream isn't copiable. 
    bool operator==(const paragraph_iterator &b) const { 
     if (_infile.bad() == b._infile.bad()) 
      return true; //all end() and uninitialized iterators equal 
     // so we can use paragraph_iterator() as end() 
     return false; //since they all are seperate strings, never equal 
    } 
    bool operator!=(const paragraph_iterator &b) const {return !operator==(b);} 
    const std::string &operator*() const { return _text;} 
}; 

int main() { 
    paragraph_iterator iter("myfile.txt"); 
    while(iter != paragraph_iterator()) { 
     // dostuff with *iter 
    } 

} 

流被封裝在迭代器中,所以如果我們有兩個迭代器到同一個文件,兩者都會得到每一行。如果你有一個帶有兩個迭代器的獨立章節類,你可能會遇到「線程化」問題。這是相當裸露的代碼,並且完全未經測試。我敢肯定,有一種方法可以用可複製的迭代器來完成,但要更復雜一些。

通常,迭代器類的實現與其迭代的數據結構密切相關。否則,我們只需要一些泛型迭代器類。

+0

感謝@MooingDuck,我使用'friend istream&operator >>(istream&i,Paragraph&p)'解決了這個問題'的方法,但您的解決方案實際上是我之前的工作。在我對代碼的最初測試中,我發現的最大問題是未初始化的paragraph_iterator與實際的_infile流具有相同的位狀態,所以主while循環不會去任何地方。我把它調整爲'paragraph_iterator(){ _infile.setstate(ios :: eofbit);現在它似乎工作。 – confusedCoder 2011-12-21 19:24:07

+0

@confusedCoder:再看一遍這段代碼,你是對的,它有幾個bug。默認的構造函數是錯誤的,等價運算符解引用空指針,在構造函數中不需要字符串的副本......但概念在那裏。 – 2011-12-22 23:24:58