# Converting string vector to integer vector

• 05-08-2010
CPlus
Converting string vector to integer vector
Hello :)

My goal is to allow the person to input a string of numbers like:
1 22 333 4444 55555 666666 7777777 88888888 999999999

and make a vector called ivec that would look like:
ivec.at(0) = 1
ivec.at(1) = 22
ivec.at(2) = 333
ivec.at(3) = 4444
ivec.at(4) = 55555
ivec.at(5) = 666666
ivec.at(6) = 7777777
ivec.at(7) = 88888888
ivec.at(8) = 999999999

How would I do this?

This is what I have so far (there's a conversion failure, but I hope the goal is clear enough):

Code:

```//user is to provide the numbers cout << "Numbers: " ; //user now provides the numbers in string form string str_version; getline( cin , str_version ); //stringstream is made stringstream ss(str_version); //string version vector is made vector<string> svec; //the string-version numbers provided by the user are written into the vector copy( istream_iterator<string>(ss) , istream_iterator<string>() , back_inserter(svec) ); //integer version vector is now made vector<int> ivec;    //this is where the conversion fails, but, atoi() or some other function, would basically //convert the string version of the number into an integer and input that at the same //slot, only in ivec this time. for (int i = 0 ; i < (sizeof(svec) - 1) ; i++) {     ivec.at(i) = atoi(svec.at(i)); } //if this worked, then operating between the numbers would be no problem, //such as adding two together cout << ivec.at(1) + ivec.at(2) << endl; //closing statements cin.clear(); cin.ignore( numeric_limits < streamsize > ::max(), '\n'); cin.get(); main();```
The best method would directly copy the integers into the vector, rather than convert them from a string version (unfortunately I'm working with what I know).

Thanks for any input :)
• 05-08-2010
rodrigorules
you dont need atoi if your gonna use stringstreams i think

Code:

```#include <vector> #include <iostream> #include <sstream> #include <string> #include <numeric> using namespace std; vector<int> vecstr_to_vecint(vector<string> vs) {         vector<int> ret;         for(vector<string>::iterator it=vs.begin();it!=vs.end();++it)         {                 istringstream iss(*it);                 int temp;                 iss >> temp;                 ret.push_back(temp);         }          return ret; } int main() {         string input, temp;         vector<string> tokens;         getline(cin, input);         istringstream iss(input);         while(iss >> temp)                 tokens.push_back(temp);                 vector<int> input_int = vecstr_to_vecint(tokens);         //now for test I will print the sum!         cout << accumulate(input_int.begin(), input_int.end(), 0) << endl; }```
edit: tested it works

I am not sure what the general consensus on exactly when streams are meant to be used but I frequently use them to convert between types...
I use istringstream if I want to insert a large string and tokenize it, I use an ostringstream if I want to insert various objects likes strings and ints and spit out a large string with .str()
• 05-08-2010
Memloop
Why not use the capabilities of the stringstream class instead of atoi()?

Code:

```#include <sstream> #include <iostream> #include <string> #include <vector> int main() {     std::string input;     std::getline(std::cin, input);     std::istringstream iss(input);     std::vector<int> vec;     int conversion_result;     while (iss >> conversion_result)     {         vec.push_back(conversion_result);         std::cout << conversion_result << std::endl;     }         return 0; }```
• 05-08-2010
grumpy
Ah, a C programmer learning C++.....

The "conversion failure" is an error message from your compiler that is emitted because atoi() accepts a (const) pointer to char (or an array of char) not a std::string. However, std::string has a method named c_str() that gives an equivalent pointer to char.

Other problems with your code (other than it being incomplete);

1) The number of elements of svec is obtained as svec.size(), not as sizeof(svec).

2) If you are using a vector's at() method, the element you fetch needs to be valid (index in the range 0 to size()-1). Fetching the third element of a 2-element vector, for example, is invalid. ivec is created with zero elements, and never resized before using the at() method. That gives undefined behaviour.

3) There is no need to use an intermediate vector<string> if you rewrite the copy() operation as copy( istream_iterator<int>(ss) , istream_iterator<int>() , back_inserter(svec) );

4) Calling main() is forbidden in C++.
• 05-08-2010
anon
Code:

`copy( istream_iterator<string>(ss) , istream_iterator<string>() , back_inserter(svec) );`
This would be OK, except you want to read integers from the stream, not strings.

Code:

`copy( istream_iterator<int>(ss) , istream_iterator<int>() , back_inserter(svec) );`
You can also use the vector's constructor that takes a pair of iterators, but be aware of the "most vexing parse" (expression interpreted as a function declaration) - note the extra parenthesis to work around that:

Code:

`vector<int> ivec((istream_iterator<string>(ss)) , istream_iterator<string>() );`
----

And if you want to get more advanced, and detect if the user input consists of integers in the first place, rather than silently swallowing errors, you can use Boost's handy lexical_cast, which throws an exception if a string is not fully convertible to target type.

Code:

`transform(istream_iterator<string>(ss), istream_iterator<string>(), back_inserter(ivec), &boost::lexical_cast<int, string>);`