【问题标题】:Creating a class with an open file stream创建具有打开文件流的类
【发布时间】:2013-11-14 11:23:38
【问题描述】:

我创建了一个应该读取 DNA 序列的类:它包含一个 if 流私有成员:

界面:

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;
} 

我看到 if 流没有打开:

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]

虽然我认为构造函数会打开 if 流。我需要做些什么来纠正这个问题,以便创建对象并包含一个开放流? (我知道我还没有包含一个析构函数,它将在对象销毁时关闭流)。

谢谢, 本。

【问题讨论】:

  • 如果尝试在构造函数之外打开流怎么办?比如:你的 main() 中的 MyDNAStream.FileStream.open("filename")?这行得通吗?
  • 代码没有太大问题,文件由于其他原因无法打开。顺便说一句,您不需要编写析构函数来关闭流。这会自动发生,因为 ifstream 析构函数会为您关闭流(令人惊讶的是有多少新手没有意识到这一点)。

标签: c++ class constructor ifstream


【解决方案1】:

您的示例显示 is_open 返回 false。我认为你应该在你的构造函数中检查文件确实是打开的,如果没有,就抛出。

在您的情况下,我怀疑这是由于将“~/Dropbox/1_20dd5.fasta”作为输入参数传递。您是否使用完整路径名进行了测试,没有 ~?我不知道处理真实路径扩展的 C++ 库(如 python 的 os.path)。

【讨论】:

  • 是的 ~ 由 shell 处理,这里没有 shell 所以 ~ 没有被正确解释。
  • 我发现问题确实是路径和 ~ 的规范:如果我也将输入文件粘贴在桌面上并且只指定文件名,那么它就可以工作。 Howe 最好为构造函数实现一个 try catch - 在 catch 之后函数不会完成并返回一个带有关闭的 if 流成员的对象吗?
  • 当意外发生时,你应该抛出 std::exception,你在调用构造函数时在 main 中捕获它,例如:codetry { Sequence_stream MyDNAStream("~/Dropbox/1_20dd5.快速”,“快速”); } {catch (std::exception& e) { //do something } 如果你没有捕捉到,那么你的程序只会进入核心。或者,如果您不想使用异常,则必须在您的类中实现一个方法来检查您创建的对象的完整性(类似于 is_open() 方法)。
猜你喜欢
  • 1970-01-01
  • 2023-01-15
  • 2013-06-24
  • 2014-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-15
  • 2021-10-05
相关资源
最近更新 更多