【问题标题】:How to read the rest of a sequence from new line and without the space? c++如何在没有空格的情况下从新行读取序列的其余部分? C++
【发布时间】:2017-08-21 13:10:46
【问题描述】:

现在看第 2 行,Cow-DNA 序列;这在第 13 行和第 24 行继续,并且......我想为每个序列获取这个长序列,忽略中间的空白和新行。

这是文件的格式:1

这是代码,它只读取前 10 个序列

ifstream file ("txt");
string line;
vector <string> vec;
stringstream s;
string name;

string strip(string & s)
{
    size_t b = s.find_first_not_of(' ');
    size_t e = s.find_last_not_of(' ');
    if (b == string::npos) {
        return "";
    } else {
        return s.substr(b, e - b + 1);
    }
}

void getSequence(){
    int i;
    int row;
    int col;
    if (file.is_open()) 
    {
        file >> row >> col;
        for (i = 0; i < row; i++) {
            vec.push_back("");
        }
        i = 0;
        while (getline(file, line)) 
        {
            file >> name;
            if (line == " ") 
            {
                continue;
            }

            vec[i % row] += strip(line);
            i++;
        }
    } 
    else {
        cerr << "Error: file did not open!" << endl;
    }
    for (const string & v : vec) {
        cout << v << endl;
    }
}

提前感谢您的帮助。

【问题讨论】:

  • 您可以使用vector.resize(row) 代替循环,getline 会按照它说的做,它会读取整行。紧随其后的是file &gt;&gt; name; 不是您所需要的。我不确定第 2-11 行如何对应 13+ 或您要如何处理该数据。
  • 这样持续了多少行?没有足够的格式信息需要了解。
  • 请查看链接。应该让您更好地了解格式。这就是我正在使用的文件。 file &gt;&gt; name; 存储每个序列的名称。
  • 你需要描述一下。上面有名字的行是我想的一个序列的开始。剩下的线是干什么用的?大块都是一个序列吗?大块的每一行是否对应于命名的行?你想要第 2 + 13 + 24 + 35 + ... 行吗?
  • 所以取第二个序列块,把它放在第一个序列块的末尾,第三个序列块放在第二个块的末尾,依此类推。我希望每个块在最后合并每个块,这变成了 10 行和 705 列的长多个序列。

标签: c++ c++11 ifstream removing-whitespace


【解决方案1】:

也许这会有所帮助。这个想法是读取行和列,然后读取标题行的行数。之后重复读取下一行,并将每行附加到正确的项目,假设这些行是交错的。

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

struct Sequence
{
    std::string name;
    std::string data;
};
using SeqVec = std::vector<Sequence>;

bool readHeader(std::ifstream& f, SeqVec& v)
{
    for (size_t i = 0; i < v.size(); ++i)
    {
        if (!(f >> v[i].name >> v[i].data))
        {
            return false;
        }
    }
    return true;
}

int readChunk(std::ifstream& f, SeqVec& v)
{
    int linesRead = 0;
    std::string chunk;
    for (size_t i = 0; i < v.size(); ++i)
    {
        if(!(f >> chunk))
        {
            break;
        }
        v[i].data += chunk;
        ++linesRead;
    }
    return linesRead;
}

int main()
{
    std::vector<Sequence> v;

    const std::string filename = "test.txt";
    std::ifstream f(filename);
    if (!f)
    {
        return -1;
    }

    int row;
    int col;
    if (f >> row >> col)
    {
        v.resize(row);
        if (!readHeader(f, v))
        {
            return -1;
        }
        for (;;)
        {
            int linesRead = readChunk(f, v);
            if (linesRead == 0 && v[0].data.size() == col)
            {
                //If we read nothing and the lines are the correct length we're done.
                break;
            }
            else if (linesRead < v.size())
            {
                //partial read is an error.
                return -1;
            }
        }
    }

    for (auto& seq : v)
    {
        std::cout << seq.name << " : " << seq.data << "\n";
    }
    return 0;
}

【讨论】:

  • 帮助很大。太感谢了。不知道struct
  • 只是小修正:改为 && if (linesRead == 0 &amp;&amp; v[0].data.size() == col), ||是需要的。所以if (linesRead == 0 || v[0].data.size() == col)。再次感谢您
  • 如果这对你有用,好吧,但假设列数对于文件是正确的,这不是正确的条件。预计总会有多个 row * 行。这些行以行数的块读取,最后,在读取了所有行之后,预计下一次读取将是 0 行,并且数据的长度是正确的。如果没有发生这种情况,则说明您的文件的列数不正确或存在其他问题。
猜你喜欢
  • 2021-08-02
  • 2022-11-15
  • 2019-05-27
  • 2019-04-05
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
相关资源
最近更新 更多