2012-10-19 24 views
14

Eventuali duplicati:
Splitting a string in C++Esiste un equivalente in C++ della funzione explode() di PHP?

In PHP, la funzione explode() avrà una stringa e tritarlo in un array separando ciascun elemento da un delimitatore specificato.

Esiste una funzione equivalente in C++?

+1

No, ma è abbastanza facile scrivere la propria implementazione. –

+1

'boost :: split' da [boost/algorithm/string.hpp] (www.boost.org/doc/html/string_algo.html) – Praetorian

+0

@KerrekSB Penso che dovresti fare una risposta prima che questo sia chiuso –

risposta

28

Ecco un semplice esempio di implementazione:

#include <string> 
#include <vector> 
#include <sstream> 
#include <utility> 

std::vector<std::string> explode(std::string const & s, char delim) 
{ 
    std::vector<std::string> result; 
    std::istringstream iss(s); 

    for (std::string token; std::getline(iss, token, delim);) 
    { 
     result.push_back(std::move(token)); 
    } 

    return result; 
} 

Usage:

auto v = explode("hello world foo bar", ' '); 

Nota: @ idea di Jerry di scrivere a un iteratore di uscita è più idiomatico per C++. In effetti, puoi fornire entrambi; un modello di output-iterator e un wrapper che produce un vettore, per la massima flessibilità.

Nota 2: se si desidera ignorare token vuoti, aggiungere if (!token.empty()).

+0

Cosa sta facendo std :: move in questo caso? È necessario? Ho compilato senza di esso dal momento che non sto usando C++ 11, e va bene. Ma qual è lo scopo in questo caso? –

+4

@ user1944429: lo spostamento evita la copia dei dati di stringa. Dal momento che non ne hai più l'uso all'interno del loop, ha senso che il vettore "rubi" direttamente i dati senza copiarli. –

+0

manca un caso, nello scenario di input di "a, b, c, d," dovrebbe restituire 5 valori compreso l'ultimo null, ma non lo è –

11

La libreria standard non include un equivalente diretto, ma è abbastanza facile da scrivere. Essendo C++, normalmente non si vuole scrivere in modo specifico su un array, ma in genere si vorrebbe scrivere l'output su un iteratore, in modo che possa andare su un array, vettore, flusso, ecc. Ciò darebbe qualcosa su questo ordine generale:

template <class OutIt> 
void explode(std::string const &input, char sep, OutIt output) { 
    std::istringstream buffer(input); 

    std::string temp; 

    while (std::getline(buffer, input, sep)) 
     *output++ = temp; 
}