1

I have had a similar problem while coding in Java, and in that instance, I used str1.split(",") to change the string of integers into an array of them.

Is there a method in C++ that has a similar function to Java's split method, or is the best way using a for loop to achieve the same goals?

Inviro
  • 23
  • 1
  • 5
  • 3
    Look at `std::istringstream` and its various `>>` operators for parsing input. You could even streamline that by using `std::copy()`/`std::copy_n()` with a `std::istream_iterator` and `std::back_inserter` to parse and insert the integers into a `std::vector` or other container of you choosing without having the manually code the actual looping logic. – Remy Lebeau Sep 09 '16 at 01:32
  • 1
    Well, the way you mentioned in Java is still a array of String, instead of integer – Adrian Shum Sep 09 '16 at 01:44
  • 1
    [See here](http://stackoverflow.com/questions/236129/split-a-string-in-c) for how to split the string. Then convert each string to integer. – M.M Sep 09 '16 at 01:46
  • @M.M I was about to post the same question too. Anyway, the answer http://stackoverflow.com/a/236803/395202 looks like what OP needs – Adrian Shum Sep 09 '16 at 01:48
  • @AdrianShum yeah, and replace `elems.push_back(item)` by `elems.push_back( std::stoi(item) )` – M.M Sep 09 '16 at 01:55

2 Answers2

2

Using std::istringstream to parse this out would certainly be more convenient.

But the question being asked is what's going to be most "efficient". And, for better or for worse, #include <iostream> is not known for its efficiency.

A simple for loop will be hard to beat, for efficiency's sake.

Assuming that the input doesn't contain any whitespace, only commas and digits:

std::vector<int> split(const std::string &s)
{
    std::vector<int> r;

    if (!s.empty())
    {
        int n=0;

        for (char c:s)
        {
            if (c == ',')
            {
                r.push_back(n);
                n=0;
            }
            else
                n=n*10 + (c-'0');
        }
        r.push_back(n);
   }
   return r;
}

Feel free to benchmark this again any istream or istream_iterator-based approach.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • They might have meant "efficient" in terms of coding time, or lines-of-code – M.M Sep 09 '16 at 01:59
  • Your solution causes undefined behaviour in case of integer overflow – M.M Sep 09 '16 at 01:59
  • As `push_back` may be costly, it would probably be more efficient to count commas, and do `r.reserve(number_of_commas+1);` Besides, integers may have the leading "-" (he didn't write it is unsigned integers). – user31264 Sep 09 '16 at 03:25
0

If ou already know the number of elements in your string, the fastest method is to use the c function sscanf which is a lot faster that istringstream (http://lewismanor.blogspot.fr/2013/07/stdstringstream-vs-scanf.html):

#include <cstdio>
#include <iostream>

using namespace std;

int main() {
    const char * the_string= "1,2,3,45";
    int numbers[4];
    sscanf(the_string, "%d,%d,%d,%d", numbers+0, numbers+1, numbers+2, numbers+3);

    // verification
    for(int i=0; i<4; i++)
        cout<<numbers[i]<<endl;
}
Frank Bessou
  • 632
  • 5
  • 8