биоинформатика — Как разбить строку и получить я хочу в C ++?

Вот такая строка: M90I4D7

Мне нужно вставить это в такую ​​структуру:

struct  CigarOp {

char     Type;   //!< CIGAR operation type (MIDNSHPX=)
uint32_t Length; //!< CIGAR operation length (number of bases)

//! constructor
CigarOp(const char type = '\0',
const uint32_t& length = 0)
: Type(type)
, Length(length)
{ }
};

это означает, что мне нужно разделить его на 3 группы, и каждая из них является CigarOp (‘M’, 90 ‘I’, 4 ‘D’, 7)

1

Решение

Предполагая, что строка имеет вид ([A-Z] [0-9] +) *, вы можете просто сделать что-то вроде этого:

#include <sstream>

...

std::vector<CigarOp> cigars;
std::istringstream parser("M90I4D7");

char c;
std::uint32_t l;

while(parser >> c >> l) {
cigars.push_back(CigarOp(c, l));
}

Обратите внимание, что этот код не выполняет никакой проверки. Если проверка необходима, одним из способов ее достижения является использование Boost.Spirit (находится на http://boost.org):

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>

#include <cstdint>
#include <iostream>

struct CigarOp {
char          Type;
std::uint32_t Length;
};

BOOST_FUSION_ADAPT_STRUCT(CigarOp, (char, Type) (std::uint32_t, Length))

int main() {
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::char_;
using boost::spirit::qi::uint_;
using boost::spirit::qi::standard::space;

std::vector<CigarOp> cigars;

std::string s = "M90I4D7";
std::string::const_iterator first = s.begin(), last = s.end();

bool r = phrase_parse(first, last, *(char_ >> uint_), space, cigars);

if(r && first == last) {
// string was well-formed
for(auto const &cigar : cigars) {
std::cout << cigar.Type << ", " << cigar.Length << '\n';
}
}
}
2

Другие решения

как насчет:

#include <cstdio>
#include <cctype>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;

struct  CigarOp {
char op;   //!< CIGAR operation type (MIDNSHPX=)
int size; //!< CIGAR operation length (number of bases)
static int parse(const char* s,vector<CigarOp>& v)
{
char* p=(char*)(s);
while(*p!=0)
{
char* endptr;
CigarOp c;
c.op = *p;
if(!isalpha(c.op)) return -1;
++p;
if(!isdigit(*p)) return -1;
c.size =strtol(p,&endptr,10);
if(c.size<=0) return -1;
v.push_back(c);
p=endptr;
}
return 0;
}
};

int main(int argc,char** argv)
{
vector<CigarOp> cigar;
if(CigarOp::parse("M90I4D7",cigar)!=0) return -1;
for(size_t i=0;i< cigar.size();++i)
{
cout << cigar[i].op << ":" << cigar[i].size << endl;
}
return 0;
}

Кстати, для биоинформатики, вы должны спросить biostars.org.

-2