读取一行并使用下一行信息 c++
Readling a line and using the next lines information c++
我是 c++ 的新手,在从输入文件读取和更改行以使用下一行并将其保存到另一个输出文件时需要帮助。
我有一个以 .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_fragmentation),它随机地将 DNA (line2) 分成一些片段,如下所示:
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;
}
我知道这是一个很长的问题,对我来说进一步解释有点困难,但我希望这个问题是有道理的。但只要有任何意见或帮助,我们将不胜感激。谢谢。
我认为您可以先阅读完整的 fastq 片段,然后将其分成多个片段,最后再次输出,从而使您的任务总体上变得容易得多。
如果你为片段创建一个结构并为其添加输入和输出运算符(operator>>
和operator<<
),那么你可以以非常简单的方式进行读写:
#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;
}
现在您的 DNA_fragmentation
代码可以将 FastqFragment 结构作为参数并同时拆分所有需要拆分的字符串。
我是 c++ 的新手,在从输入文件读取和更改行以使用下一行并将其保存到另一个输出文件时需要帮助。
我有一个以 .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_fragmentation),它随机地将 DNA (line2) 分成一些片段,如下所示:
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;
}
我知道这是一个很长的问题,对我来说进一步解释有点困难,但我希望这个问题是有道理的。但只要有任何意见或帮助,我们将不胜感激。谢谢。
我认为您可以先阅读完整的 fastq 片段,然后将其分成多个片段,最后再次输出,从而使您的任务总体上变得容易得多。
如果你为片段创建一个结构并为其添加输入和输出运算符(operator>>
和operator<<
),那么你可以以非常简单的方式进行读写:
#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;
}
现在您的 DNA_fragmentation
代码可以将 FastqFragment 结构作为参数并同时拆分所有需要拆分的字符串。