我想逐行同时阅读两个FASTA
个文件。我有以下代码逐行读取一个文件。
#include <iostream>
#include <fstream>
int main( int argc, char **argv ){
if( argc <= 1 ){
std::cerr << "Usage: "<<argv[0]<<" [infile]" << std::endl;
return -1;
}
std::ifstream input(argv[1]);
if(!input.good()){
std::cerr << "Error opening '"<<argv[1]<<"'. Bailing out." << std::endl;
return -1;
}
std::string line, name, content;
while( std::getline( input, line ).good() ){
if( line.empty() || line[0] == '>' || line[0] == '@' ){ // Identifier marker
if( !name.empty() ){ // Print out what we read from the last entry
std::cout << name << " : " << content << std::endl;
name.clear();
}
if( !line.empty() ){
name = line.substr(1);
}
content.clear();
} else if( !name.empty() ){
if( line.find(' ') != std::string::npos ){ // Invalid sequence--no spaces allowed
name.clear();
content.clear();
} else {
content += line;
}
}
}
if( !name.empty() ){ // Print out what we read from the last entry
std::cout << name << " : " << content << std::endl;
}
return 0;
}
但是,我想为多个文件执行此操作。 E,g我有两个文件,file1和file2。执行以下操作。
read file1 line
do some operation
read file2 line
do some operation
repeat till file 1 and file 2 finishes
注意:我不想一次读取file1的所有行,然后读取file2的所有行。我想要一行来自file1,一行来自file2,第二行来自file1,第二行来自file2,依此类推。
更新
文件1
@r0/1
TATTCTTCCGCATCCTTCATACTCCTGCCGGTCAG
AAA
+
EDCCCBAAAA@@@@?>===<;;9:99987776554678
@r1/1
TGATAGATCTCTTTTTTCGCGCCGACATCTACGCC
+
EDCCCBAAAA@@@@?>===<;;9:99987776554
@r2/1
CACGCCCTTTGTAAGTGGACATCACGCCCTGAGCG
+
EDCCCBAAAA@@@@?>===<;;9:99987776554
file2的
@r0/2
GAATACTGGCGGATTACCGGGGAAGCTGGAGC
+
EDCCCBAAAA@@@@?>===<;;9:99987776
@r1/2
AATGTGAAAACGCCATCGATGGAACAGGCAAT
+
EDCCCBAAAA@@@@?>===<;;9:99987776
@r2/2
AACGCGCGTTATCGTGCCGGTCCATTACGCGG
+
EDCCCBAAAA@@@@?>===<;;9:99987776
其实我尝过类似
的东西std::ifstream input(argv[1]);
std::ifstream input1(argv[2]);
std::string line, name, content;
std::string line1, name1, content1;
while( std::getline( input, line ).good() && std::getline( input1, line1 ).good() ){
//file1 line operation
// file2 line operation
}
但如果线条不同,这不会起作用。阅读后的行看起来像
@r0/1 TATTCTTCCGCATCCTTCATACTCCTGCCGGTCAGAAA+EDCCCBAAAA@@@@?>===<;;9:99987776554678
答案 0 :(得分:1)
虽然通过摘录文件可以更容易地判断出您需要什么样的解析。我刚刚下载了这个文件Homo_sapiens.GRCh38.dna.chromosome.22.fa
,其格式如下:
22 dna:染色体染色体:GRCh38:22:1:50818468:1 REF NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN CTGGTCTTGAACTCCTGACCTCAAGTGATCTGCCCACCTCCGCCTCCCAAACTGCTAGAA TTACAGGCGTGAGCAACCACTCCCTACCTTCCCCCATTTTTATAATAAACATTCTACACA GGGCTCCTGCCAGCCCTCCAAGCTTCTCACTTTGAGAAGCACAGTCCGCTCTGTCAGACT
由于第一行是文件唯一的,并且没有出现两次,我只是将其删除,而不是为编写解析它的代码而负担自己。但是,如果您的项目需要它存在,我将包含一个功能来完成它。
所以,你需要的第一件事就是从文件中读取。由于我们知道条目是统一的,因此我们可以在不使用getLine();
或任何花哨的情况下四处走动。根据您的期望,有两种方法可以实现。
第一种方法,如果您需要从两个文件中读取,直到其中一个文件到达结束:
void readLine(string path1, string path2){
ifstream inOne(path1);
ifstream inTwo(path2);
while( !inOne.eof() & !inTwo.eof() ){
string strOne, strTwo;
inOne>>strOne;
inTwo>>strTwo;
cout<<"1 "<<strOne<<endl;
cout<<"2 "<<strTwo<<endl;
}
}
但是,如果您需要继续读取其中一个文件,请使用以下内容:
while( !inOne.eof() | !inTwo.eof() ){
string strOne, strTwo;
if(!inOne.eof())
inOne>>strOne;
if(!inTwo.eof())
inTwo>>strTwo;
cout<<"1 "<<strOne<<endl;
cout<<"2 "<<strTwo<<endl;
}
现在,至于你想在每一行上执行的实际格式,你很可能注意到我没有写任何东西来处理它。那是因为在我看来,最好的方法就是编写另一个能够做到这一点的功能。你可以称之为formatLine(string line);
。然后使用我提供的代码,添加对该函数的调用并相应地修改输出。我无法告诉你究竟是什么样的,因为你可以定义formatLine();
来返回从行中提取的元素数组,或者你可以返回vector
这总是一个好主意,如果元素数量可能有所不同
现在对于第一行,您可以创建一个仅用于读取该行的函数,因为它非常不同并且可能需要不同的格式。
void readFirst(string path){
ifstream inOne(path, ios::in | ios::binary); //ORed bitfield to get unformatted binary
char ch=0;
while(ch != '\n'){
inOne.get(ch);
cout<<ch<<endl;
}
}
然后,您可能希望将每个字符存储在c字符串中,或者附加常规字符串。另外,请不要忘记在使用inOne.close();
完成后关闭每个流
的 UPD。强>
只要行中没有空格,您仍然可以将此代码用于您提供的文件,因为提取器iostream
会将它们视为分隔符,因此将其视为新行。
但是,如果您需要确保分隔符不会影响有序提取,请使用我包含的最后一段代码。 ios::binary
会阻止格式化,因此您不会丢失任何字符,并且您将能够确切地知道何时移动到新行。它可能看起来像:
void readLine(string path1, string path2){
ifstream inOne(path1, ios::in | ios::binary);
ifstream inTwo(path2, ios::in | ios::binary);
while( !inOne.eof() | !inTwo.eof() ){
string strOne, strTwo;
strOne=readLineBin(inOne);
strTwo=readLineBin(inTwo);
cout<<"1 "<<strOne<<endl;
cout<<"2 "<<strTwo<<endl;
}
}
string readLineBin(ifstream& in){
string line="";
char ch=0;
while(ch != '\n' & !in.eof()){
in.get(ch);
line+=ch;
}
return line;
}