读取一行并使用下一行信息c++; 我是C++新手,在从输入文件中读取和更改行以使用下一行并保存到另一个输出文件时,需要帮助。

读取一行并使用下一行信息c++; 我是C++新手,在从输入文件中读取和更改行以使用下一行并保存到另一个输出文件时,需要帮助。,c++,file-io,line,C++,File Io,Line,我有一个以.fastq格式存储的单个DNA序列的示例,其结构如下 @Read_1 AGACUUUACGCT + ++//187-,/02 所以每个DNA序列有四行信息 我的目标是将DNA串(第2行,长度12)分成不同的随机长度片段,并将每个片段保存为一个单独的新序列。但是为了保持.fastq结构,我需要保留第3行和第4行的信息!因此,理想的输出是: @Read_1_1 AGAC + ++// @Read_1_2 UU + 18 @Read_1_3 UACGCT + 7-,/02 在这个理想的

我有一个以.fastq格式存储的单个DNA序列的示例,其结构如下

@Read_1
AGACUUUACGCT
+
++//187-,/02
所以每个DNA序列有四行信息

我的目标是将DNA串(第2行,长度12)分成不同的随机长度片段,并将每个片段保存为一个单独的新序列。但是为了保持.fastq结构,我需要保留第3行和第4行的信息!因此,理想的输出是:

@Read_1_1
AGAC
+
++//
@Read_1_2
UU
+
18
@Read_1_3
UACGCT
+
7-,/02
在这个理想的输出中,输入的第4行被分割以匹配每个DNA片段(但是我可以用substr来完成这项工作,所以这不是问题)。我的问题是,当我拆分DNA序列(第2行)并将其保存为新的读取时,我需要第3行和第4行的信息

<>我用C++编写代码,我做了一些功能,并做了一些不同的尝试,失败了:

当我打开文件时,我创建了一个函数(DNA_片段),它将DNA(第2行)随机拆分为一些片段,如下所示:

AGAC
UU
UACGCT
因此,当我使用此函数时,我正在读取第2行,然后将这些片段保存到std::vectorstd::string中,并使用for循环将这些片段及其读取(从第1行)保存到一个新文件中,给我输入:

@Read_1_1
AGAC
@Read_1_2
UU
@Read_1_3
UACGCT
我的问题是我不知道如何为每个新片段添加第3行和第4行,因为它们是在我打开并读取原始文件的第2行时创建的。如何从下一行中提取信息

要读取文件并分离函数,请使用以下命令:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

std::string fafq_seq(std::string in_name, std::string out_name) {
    std::ifstream myfile(in_name);
    std::ofstream out_file(out_name);

    if (myfile.is_open() && out_file.is_open())
    {
        std::string line;
        while( std::getline(myfile,line) )
        {
            int ID = 1;
            std::string read_ID;
            
            // This is line 1, which always match with @
            if (line.rfind("@",0) == 0) {
                continue;
            } // Then reading line 2  the DNA sequence
            else if (line.rfind("A", 0) == 0 ||
                line.rfind("T", 0) == 0 ||
                line.rfind("G", 0) == 0 ||
                line.rfind("C", 0) == 0){

                std::string Seq = line;
                
                // creating a vector with each of the DNA pieces using my DNA_fragmentation function
                std::vector<std::string> Damage = DNA_fragmentation(Seq,2,8);
                
                // For each fragment im adding a new read and saving the output
                for (int i=0; i<Damage.size();i++){

                    // adding what corresponds to line 1 starting with @
                    out_file << "@Read_" << ID << "_" << i+1 << std::endl;
                    
                    // adding the DNA pieces
                    out_file << Damage[i] << std::endl;
                }
                ID += 1;
            }
            else {
                // iterating through line 3 and 4, which is where im not sure how to handle my problem
                out_file << line << std::endl;
            }
        }
        out_file.close();
        myfile.close();
    }
}

int main() {

    std::string File = "TestSeq.fastq";
    fafq_seq(File,"Test_out.fastq");

    return 0;
}
#包括
#包括
#包括
#包括
std::string fafq_seq(std::string in_name,std::string out_name){
std::ifstream myfile(以_名称);
std::流输出文件(输出名称);
if(myfile.is_open()&&out_file.is_open())
{
std::字符串行;
while(std::getline(myfile,line))
{
int-ID=1;
std::字符串读取ID;
//这是第1行,它总是与@
if(line.rfind(“@”,0)==0){
继续;
}//然后读取第2行的DNA序列
else如果(line.rfind(“A”,0)=0||
行.rfind(“T”,0)==0||
行.rfind(“G”,0)==0||
行.rfind(“C”,0)==0){
std::string Seq=行;
//使用我的DNA_碎片函数创建包含每个DNA片段的载体
std::载体损伤=DNA片段化(Seq,2,8);
//对于每个片段,我添加一个新的读取并保存输出

对于(inti=0;i我认为,通过首先读取完整的fastq片段,然后将其拆分为多个片段,最后再次输出,可以使任务总体上更加容易

如果为片段创建一个结构并添加输入和输出操作符(
操作符>>
操作符(std::istream&in,FastqFragment&frag)
{
std::getline(in,frag.ID);
if(frag.ID.size()==0 | | frag.ID[0]!='@')){
in.setstate(std::ios_base::failbit);
返回;
}
std::getline(in,frag.sequence);
标准::getline(in,frag.delim);
if(frag.delim.size()==0 | | frag.delim[0]!='+')){
in.setstate(std::ios_base::failbit);
返回;
}
标准::getline(英寸,框架质量值);
返回;
}

std::ostream&operator非常感谢您对结构和如何使用结构的建议!这非常有用。这到底是做什么的?在.setstate(std::ios_base::failbit);?我可以看到在frag.ID的情况下,它会检查格式是否正确,但我不确定如何理解“set state…”。我可以读到它改变了标志。那么这像是引发了一个错误吗?@RAHenriksen查看流,它是
在(在>>tmp中)
工作的原因。
setstate
做的是,它将流标记为“有故障”这会导致循环终止。这可能不是您希望在程序中执行的行为,例如,您可能还希望忽略错误行,然后尝试向前扫描以找到下一个好片段的开头。但这取决于您的决定。@RAHenriksen您也可以在此处阅读更多内容:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

struct FastqFragment
{
    std::string ID;
    std::string sequence;
    std::string delim;
    std::string quality_value;
};

std::istream& operator>>(std::istream& in, FastqFragment& frag)
{
    std::getline(in, frag.ID);
    if (frag.ID.size() == 0 || frag.ID[0] != '@') {
        in.setstate(std::ios_base::failbit);
        return in;
    }

    std::getline(in, frag.sequence);
    std::getline(in, frag.delim);
    if (frag.delim.size() == 0 || frag.delim[0] != '+') {
        in.setstate(std::ios_base::failbit);
        return in;
    }

    std::getline(in, frag.quality_value);
    return in;
}

std::ostream& operator<<(std::ostream& out, const FastqFragment& frag)
{
    out << frag.ID << '\n';
    out << frag.sequence << '\n';
    out << frag.delim << '\n';
    out << frag.quality_value << '\n';
    return out;
}
int main()
{
    std::ifstream in("sequence.txt");

    std::vector<FastqFragment> frags;
    for (FastqFragment tmp; in >> tmp;) {
        frags.push_back(tmp);
    }

    // Insert code for mutating the fragments

    for (const auto& f : frags)
        std::cout << f;

    // or

    std::ofstream out("output.txt");
    for (const auto& f : frags)
        out << f;
}