2013-11-14 45 views
0

我創建這是應該的DNA序列讀取類的打開文件:它包含一個如果流私有成員:創建一類流

接口:

class Sequence_stream { 
    const char* FileName; 
    std::ifstream FileStream; 
    std::string FileFormat; 

public: 
    Sequence_stream(const char* Filename, std::string Format); 
    NucleotideSequence get(); 
}; 

實施:

Sequence_stream::Sequence_stream(const char* Filename, std::string Format) 
{ 
    FileName = Filename; 
    FileStream.open(FileName); 
    FileFormat = Format; 
    std::cout << "Filestream is open: " << FileStream.is_open() << std::endl; 
} 

NucleotideSequence Sequence_stream::get() 
{ 
    if (FileStream.is_open()) 
    { 
     char currentchar; 
     int basepos = 0; 
     std::string name; 
     std::vector<Nucleotide> sequence; 
     currentchar = FileStream.get(); 
     if (currentchar == '>' && false == FileStream.eof()) { // Check that the start of the first line is the fasta head character. 
      currentchar = FileStream.get(); // Proceed to get the full name of the sequence. Get characters until the newline character. 
      while(currentchar != '\n' && false == FileStream.eof()) 
      { 
       if (true == FileStream.eof()) { 
        std::cout << "The file ends before we have even finished reading in the name. Returning an empty NucleotideSequence" << std::endl; 
        return NucleotideSequence(); 
       } 
       name.append(1, currentchar); 
       currentchar = FileStream.get(); 
      } // done getting names, now let's get the sequence. 
      currentchar = FileStream.get(); 
      while(currentchar != '>' && false == FileStream.eof()) 
      { 
       if(currentchar != '\n'){ 
        basepos++; 
        sequence.push_back(Nucleotide(currentchar, basepos)); 
       } 
       currentchar = FileStream.get(); 
      } 
      if(currentchar == '>') 
      { 
       FileStream.unget(); 
      } 
      return NucleotideSequence(name, sequence); 
     } else { 
      std::cout << "The first line of the file was not a fasta format description line beginning with '>'. Are you sure the file is of FASTA format?" << std::endl; 
      return NucleotideSequence(); 
     } 

    } else { 
     std::cout << "The filestream is not open..." << std::endl; 
     return NucleotideSequence(); 
    } 
} 

但是如果我測試:

int main() 
{ 
    std::cout << "Let's try and read in a sequence!" << std::endl; 
    std::cout << "First we'll create a stream!" << std::endl; 
    Sequence_stream MyDNAStream("~/Dropbox/1_20dd5.fasta", "fasta"); 
    std::cout << "Done!" << std::endl; 
    std::cout << "Now let's try and get a sequence!" << endl; 
    NucleotideSequence firstsequence = MyDNAStream.get(); 
    return 0; 
} 

我看到,如果流不開放:

Let's try and read in a sequence! 
First we'll create a stream! 
Filestream is open: 0 
Done! 
The filestream is not open... 
logout 

[Process completed] 

雖然我還以爲構造函數打開,如果流。在創建對象幷包含開放流時,我需要做些什麼來糾正此問題? (我知道我還沒有包含一個析構函數,它會在對象被破壞時關閉流)。

謝謝, 本。

+0

如果您嘗試在構造函數之外打開流,該怎麼辦?像:MyDNAStream.FileStream.open(「文件名」)在你的主要()?那樣有用嗎? – cen

+0

代碼沒有太大的錯誤,該文件由於某些其他原因無法打開。順便說一句,你不需要編寫一個析構函數來關閉流。這會自動發生,因爲ifstream析構函數會爲你關閉流(令人驚訝的是有多少新手沒有意識到這一點)。 – john

回答

2

您的示例顯示is_open返回false。我認爲你應該檢查你的構造函數,該文件確實是打開的,如果不是,則拋出。

在你的情況,我懷疑這是由於傳遞「〜/ Dropbox/1_20dd5.fasta」作爲輸入參數。你用完整的路徑名進行測試,沒有〜?我不知道處理實際路徑擴展的C++庫(如python的os.path)。

+0

是'〜'是由shell處理的,這裏沒有shell,因此'〜'不能正確解釋。 – john

+0

我發現問題的確是路徑和〜的規範:如果我也將輸入文件粘貼在桌面上,只需指定文件名即可。 Howe最好是爲構造函數實現一個try catch - 不管函數完成一個catch並返回一個封閉的if流成員的對象嗎? – Ward9250

+0

當發生意外事件時,您應該拋出w std :: exception,在調用構造函數時捕獲到main中,例如: 'code' try { Sequence_stream MyDNAStream(「〜/ Dropbox/1_20dd5.fasta」, 「FASTA」); } { { // 捕捉(標準::異常&E)做一些 } 如果你沒有趕上,那麼你的程序是簡單地將核心。或者,如果您不想使用異常,則必須在類中實現一個方法來檢查您創建的對象的完整性(類似於is_open()方法)。 – user2991479