Manera correcta de dividir un std::string en un vector<string>

Resuelto softwarematter asked hace 13 años • 12 respuestas

¿Cuál es la forma correcta de dividir una cadena en un vector de cadenas? El delimitador es un espacio o una coma.

softwarematter avatar Apr 10 '11 03:04 softwarematter
Aceptado

Una forma conveniente sería la biblioteca de algoritmos de cadenas de Boost .

#include <boost/algorithm/string/classification.hpp> // Include boost::for is_any_of
#include <boost/algorithm/string/split.hpp> // Include for boost::split
// ...

std::vector<std::string> words;
std::string s;
boost::split(words, s, boost::is_any_of(", "), boost::token_compress_on);
UncleBens avatar Apr 09 '2011 20:04 UncleBens

Para cadenas separadas por espacios, puede hacer esto:

std::string s = "What is the right way to split a string into a vector of strings";
std::stringstream ss(s);
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

Producción:

What
is
the
right
way
to
split
a
string
into
a
vector
of
strings

cadena que tiene coma y espacio

struct tokens: std::ctype<char> 
{
    tokens(): std::ctype<char>(get_table()) {}
 
    static std::ctype_base::mask const* get_table()
    {
        typedef std::ctype<char> cctype;
        static const cctype::mask *const_rc= cctype::classic_table();
 
        static cctype::mask rc[cctype::table_size];
        std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));
 
        rc[','] = std::ctype_base::space; 
        rc[' '] = std::ctype_base::space; 
        return &rc[0];
    }
};
 
std::string s = "right way, wrong way, correct way";
std::stringstream ss(s);
ss.imbue(std::locale(std::locale(), new tokens()));
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

Producción:

right
way
wrong
way
correct
way
Sarfaraz Nawaz avatar Apr 09 '2011 20:04 Sarfaraz Nawaz

Puedes usar getline con delimitador:

string s, tmp; 
stringstream ss(s);
vector<string> words;

while(getline(ss, tmp, ',')){
    words.push_back(tmp);
    .....
}
James LT avatar Mar 20 '2019 14:03 James LT
vector<string> split(string str, string token){
    vector<string>result;
    while(str.size()){
        int index = str.find(token);
        if(index!=string::npos){
            result.push_back(str.substr(0,index));
            str = str.substr(index+token.size());
            if(str.size()==0)result.push_back(str);
        }else{
            result.push_back(str);
            str = "";
        }
    }
    return result;
}

dividir("1,2,3",",") ==> ["1","2","3"]

dividir("1,2,",",") ==> ["1","2",""]

dividir("1token2token3","token") ==> ["1","2","3"]

Shiqi Ai avatar Oct 25 '2017 23:10 Shiqi Ai