C++ 逐行同时读取两个文件
我想逐行同时阅读两个C++ 逐行同时读取两个文件,c++,fasta,C++,Fasta,我想逐行同时阅读两个FASTA文件。我有以下代码逐行读取一个文件 #include <iostream> #include <fstream> int main( int argc, char **argv ){ if( argc <= 1 ){ std::cerr << "Usage: "<<argv[0]<<" [infile]" << std::endl; return
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;
}
注意:我不想一次读取文件1的所有行,然后再读取文件2的所有行。我想要一行来自file1,一行来自file2,第二行来自file1,第二行来自file2,依此类推
更新
file1
@r0/1
TATTCTTCCGCATCCTTCATACTCCTGCCGGTCAG
AAA
+
EDCCCBAAAA@@@@?>===<;;9:99987776554678
@r1/1
TGATAGATCTCTTTTTTCGCGCCGACATCTACGCC
+
EDCCCBAAAA@@@@?>===<;;9:99987776554
@r2/1
CACGCCCTTTGTAAGTGGACATCACGCCCTGAGCG
+
EDCCCBAAAA@@@@?>===<;;9:99987776554
但如果线路不同,这就行不通了。阅读后的句子看起来像
@r0/1 TATTCTTCCGCATCCTTCATACTCCTGCCGGTCAGAAA+EDCCCBAAAA@@@@?>===<;;9:99987776554678
@r0/1 TATTCTTCCGCATCCTTCATACTCCTGCCGGTCAGAAA+EDCCCBAAAA@@?>==尽管通过文件摘录更容易判断您需要哪种解析。我刚刚下载了这个文件Homo_sapiens.GRCh38.dna.chromose.22.fa
,格式如下:
22 dna:染色体:GRCh38:22:1:50818468:1参考文献
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
CTGGTCTTGACTCCTGACTCAGTGATCCCACTCCGCCTCCCAAACTGCTAGAA
TTACAGGCGTGAGCACACTCTCTCTCTCTCTCTCTCATATAAAACATCTACCA
GGGCTCGCGCTCCAGCTCCAAGCCTTCTCACTTCTGAGAGAGACAGTCTCTCAGACT
由于文件中的第一行是唯一的,并且没有出现两次,所以我只是删除了它,而不是编写代码来解析它。但是,如果您的项目需要它存在,我将包括一个函数来完成它
因此,您需要做的第一件事是实际读取文件。因为我们知道条目是统一的,所以我们不需要使用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;
}
}
然后,您可能希望将每个字符存储在一个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;
}
void readLine(字符串路径1、字符串路径2){
ifstream inOne(路径1,ios::in | ios::binary);
ifstream inTwo(路径2,ios::in | ios::binary);
而(!inOne.eof()|!inTwo.eof()){
字符串strOne,strTwo;
strOne=readLineBin(inOne);
strTwo=readLineBin(inTwo);
您可以在现有声明下面声明另一个std::ifstream
,例如std::ifstream输入(argv[2]);
如果文件可能有不同的行数,您需要修改while循环。@Bernard这将如何工作?输入argv[1]或argv[2]中会有什么内容
@AwaitedOne:好吧,假设您传递了两个参数,那么您将得到第一个和第二个参数。检查argc
以了解有多少个参数。(argv[0]
按惯例是您的程序名)@MSalters我已经更新了我的问题,请关注上面的更新。谢谢你的回答。如果行与上面的更新不同,该怎么办。@等待我在原始回答中添加了一行,但每行都不是完整的(顺序+整体质量)一起,它分布在许多行上。@waitiedone你想让它们看起来像这样吗?@r0/1 tattcttccgcatccttcctcagaaa+EDCCCBAAAA@@@?>====@waitiedone然后在readLinebin()中用-/code>替换-/code>
。这将生成所需的行,但是您将丢失@
,但我认为这并不重要。注意:由于文本文件以@
开头,第一行可能是空字符串。此外,由于保留了新行字符,您希望在其中包含一个代码,以空格替换它
@r0/1 TATTCTTCCGCATCCTTCATACTCCTGCCGGTCAGAAA+EDCCCBAAAA@@@@?>===<;;9:99987776554678
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;
}
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;
}
}
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;
}