2013-03-25 23 views
7

C'è qualche metodo per convertire un vettore in un vettore in C++, win32?convert <vector><string> TO <vector><int> C++, Win32

Ho questo vettore stringa con i numeri:

std::vector<std::string> DataNumbers; 

Ho bisogno di convertire questa stringa vettore nel vettore intero.

+0

Che cosa è esattamente il vostro obiettivo qui? In che formato sono i numeri? Quanto è importante la performance rispetto alla leggibilità? –

+0

Ho solo bisogno di numeri interi. E poi vorrei moltiplicare per alcuni numeri da questo vettore int –

risposta

2

Prova questo:

std::vector<std::string> DataNumbers; 
    // Fill DataNumbers 
    std::vector<int> intNumbers; 
    for (int i=0; i<= 5; i++) 
    { 
    int num = atoi(DataNumbers.at(i).c_str()); 
    intNumbers.push_back(num); 
    } 
+1

Penso che le soluzioni precedenti fossero buone, ma questo funziona bene per me, perché il mio compilatore non ha "caratteristiche C++ 11". Quindi grazie! –

+3

Non credo che fare affidamento su lunghezze hardcoded e utilizzare le funzioni legacy C sia una buona soluzione. Se non hai C++ 11, usa la risposta di Richard J Ross e cambia 'for (auto & s: input)' a 'for (vector :: iterator it = DataNumbers.begin(); it! = DataNumbers. end(); it ++) 'oltre a' std :: stringstream parser (s); 'a' std :: stringstream parser (* it); '. – us2012

+0

Questo codice mi ha dato il cancro. – Puppy

4

Il C++ modo di fare è questo:

vector<std::string> input = ...; 
vector<int> output; 

for (auto &s : input) { 
    std::stringstream parser(s); 
    int x = 0; 

    parser >> x; 

    output.push_back(x); 
} 

Senza sapere che cosa si vuole fare quando fallisce l'ingresso, non c'è molto altro da dire qui.

+0

Grazie. Ma cosa significa "s" nel ciclo for? –

+1

iteratore sul vettore di stringa – Alon

+1

@alon no, è una copia della stringa – jrok

19

Dato:

std::vector<std::string> DataNumbers; 
// Fill DataNumbers 
std::vector<int> Data; 

È possibile utilizzare std::transform. Utilizzare un valore std::back_inserter per inserire i valori nello std::vector<int>. Per la funzione unaria, utilizzare un'espressione lambda che utilizza std::stoi per convertire le stringhe in numeri interi.

std::transform(DataNumbers.begin(), DataNumbers.end(), std::back_inserter(Data), 
       [](const std::string& str) { return std::stoi(str); }); 

Ed ecco una versione senza lambda (utilizzando std::bind invece):

typedef int(*stoi_type)(const std::string&, std::size_t*, int); 
std::transform(DataNumbers.begin(), DataNumbers.end(), std::back_inserter(Data), 
       std::bind(static_cast<stoi_type>(&std::stoi), 
         std::placeholders::_1, nullptr, 10)); 
+0

Sarei esitante a impazzire con i lambda. In genere sono più lenti rispetto all'utilizzo di un ciclo for e possono causare la leggibilità a lungo termine. Per non parlare del fatto che non tutti i compilatori li supportano pienamente, ancora. –

+0

@ RichardJ.Ross C'è un singolo lambda lì dentro, non sono sicuro di come sia "impazzire". Inoltre, non penso che nessun compilatore non riesca a supportare un lambda così semplice come non oserebbe menzionare * nulla * sulla conformità di C++ 11 nei loro documenti ... – us2012

+1

@ us2012 Potrei avere un compilatore che supporta solo 'auto' e' decltype' e diciamo che ha "caratteristiche C++ 11", no? Inoltre, ho votato la tua risposta. –

1

Che dire:

#include <algorithm> 
#include <boost/lexical_cast.hpp> 

template<typename C1, typename C2> 
void castContainer(const C1& source, C2& destination) 
{ 
    typedef typename C1::value_type source_type; 
    typedef typename C2::value_type destination_type; 
    destination.resize(source.size()); 
    std::transform(source.begin(), source.end(), destination.begin(), boost::lexical_cast<destination_type, source_type>); 
} 

Può convertire vettore < stringa> nel vettore < int> e anche altro contenitore < T1> nel contenitore2 < T2>, ad esempio elenco -> elenco.

codice completo:

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <string> 
#include <boost/lexical_cast.hpp> 

template<typename C1, typename C2> 
void castContainer(const C1& source, C2& destination) 
{ 
    typedef typename C1::value_type source_type; 
    typedef typename C2::value_type destination_type; 
    destination.resize(source.size()); 
    std::transform(source.begin(), source.end(), destination.begin(), boost::lexical_cast<destination_type, source_type>); 
} 

template<typename T, typename T2> 
std::vector<T>& operator<<(std::vector<T>& v, T2 t) 
{ 
    v.push_back(T(t)); 
    return v; 
} 

main(int argc, char *argv[]) 
{ 
    std::vector<std::string> v1; 
    v1 << "11" << "22" << "33" << "44"; 
    std::cout << "vector<string>: "; 
    std::copy(v1.begin(), v1.end(), std::ostream_iterator<std::string>(std::cout, ", ")); 
    std::cout << std::endl; 

    std::vector<int> v2; 
    castContainer(v1, v2); 

    std::cout << "vector<int>: "; 
    std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, ", ")); 
    std::cout << std::endl; 
}