C++ 使用打开的文件流创建类
我创建了一个类,该类应该读取DNA序列:它包含一个if流私有成员: 接口:C++ 使用打开的文件流创建类,c++,class,constructor,ifstream,C++,Class,Constructor,Ifstream,我创建了一个类,该类应该读取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(); };
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();
}
}
虽然我认为构造函数会打开if流。当对象被创建并包含一个开放流时,我需要做什么来纠正这一点?(我知道我还没有包括一个析构函数,它将在销毁对象时关闭流)
谢谢,
Ben.您的示例显示,is\u open返回false。我认为您应该在构造函数中检查文件是否确实已打开,如果未打开,则抛出
在您的情况下,我怀疑这是由于将“~/Dropbox/1_20dd5.fasta”作为输入参数传递所致。您是否使用完整路径名进行测试,没有~?我不知道处理真实路径扩展的C++库(比如Python的操作系统.PATH)。如果你尝试在构造函数之外打开流,那会怎么样?比如:MyDNAStream.FileStream.open(“filename”)在main()中?这行吗?代码没有太大问题,文件由于其他原因无法打开。顺便说一句,关闭流不需要编写析构函数。这将自动发生,因为ifstream析构函数将为您关闭流(令人惊讶的是,有多少新手没有意识到这一点)。是的
~
由shell处理,这里没有shell,所以~
的解释不正确。我发现问题确实是路径和~:如果我也将输入文件粘贴在桌面上,只需指定文件名,它就可以工作了。Howe最好为构造函数实现一个try-catch-函数在catch之后不会结束并返回一个带有关闭的if流成员的对象吗?当发生意外情况时,应该抛出w std::exception,调用构造函数时在main中捕获它,如:code
try{Sequence_stream MyDNAStream(“~/Dropbox/120dd5.fasta”,“fasta”);}{catch(std::exception&e){//do something}如果您不捕获,那么您的程序将直接进入内核。或者,如果您不想使用异常,则必须在类中实现一个方法来检查您创建的对象的完整性(类似于is_open()方法)。
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]