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