148 votes

L'analyse d'une délimité par des virgules std::string

Si j'ai un std::string contenant une liste séparée par des virgules des nombres, ce qui est la façon la plus simple d'analyser les chiffres et les mettre dans un tableau d'entiers?

Je ne veux pas généraliser ce dans l'analyse de tout autre chose. Juste une simple chaîne de séparées par une virgule des nombres entiers tels que "1,1,1,1,2,1,1,1,0".

164voto

user229321 Points 304
#include <vector>
#include <string>
#include <sstream>


std::string str = "1,2,3,4,5,6";
std::vector<int> vect;

std::stringstream ss(str);

int i;

while (ss >> i)
{
    vect.push_back(i);

    if (ss.peek() == ',')
        ss.ignore();
}

147voto

Zoomulator Points 7692

Quelque chose de moins verbeux, les mst et la prend n'importe quoi séparés par une virgule.

stringstream ss( "1,1,1,1, or something else ,1,1,1,0" );
vector<string> result;

while( ss.good() )
   {
   string substr;
   getline( ss, substr, ',' );
   result.push_back( substr );
   }

67voto

Jerry Coffin Points 237758

Encore une autre, assez différent, de l'approche: à l'aide d'un paramètre régional qui traite des virgules comme un espace blanc:

#include <locale>
#include <vector>

struct csv_reader: std::ctype<char> {
    csv_reader(): std::ctype<char>(get_table()) {}
    static std::ctype_base::mask const* get_table() {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());

        rc[','] = std::ctype_base::space;
        rc['\n'] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
}; 

Pour l'utiliser, vous imbue() un flux de données avec les paramètres régionaux qui comprend cette facette. Une fois que vous avez fait cela, vous pouvez lire les numéros comme si les virgules n'étaient pas là du tout. Juste pour exemple, nous allons lire délimité par des virgules numéros de l'entrée, et à écrire, puis à partir d'un par ligne sur la sortie standard:

#include <algorithm>
#include <iterator>
#include <iostream>

int main() {
    std::cin.imbue(std::locale(std::locale(), new csv_reader()));
    std::copy(std::istream_iterator<int>(std::cin), 
              std::istream_iterator<int>(),
              std::ostream_iterator<int>(std::cout, "\n"));
    return 0;
}

18voto

TC. Points 1704

Solution de rechange à l'aide des algorithmes génériques et coup de pouce.Générateur de jetons:

struct ToInt
{
    int operator()(string const &str) { return atoi(str.c_str()); }
};

string values = "1,2,3,4,5,9,8,7,6";

vector<int> ints;
tokenizer<> tok(values);

transform(tok.begin(), tok.end(), back_inserter(ints), ToInt());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X