2

Brand new to c++ and im having difficulty splitting on a string. I have seen some examples of this on stack overflow, but I could not get the samples to work when looping in the for loop.

Essentially I have an array of strings that looks like.

    const string userData[] =
   {"A1,John,Smith,smithJ@mail.com,42",
   "B2,Jane,Doe,jd@gmailcom,121,2",
   "C3,Mickey,Mouse,mouseman@mail.com,20"
   };   

Below is the closest I have gotten to a solution myself

 string s;
 vector<istringstream> streamV;
 vector<string> stringV;
 for(const auto& str : userData)
 {
      istringstream nasa { str };
      getline(nasa, s, ',');
      stringV.push_back(s);

 }
 cout << stringV[0] << endl;
 cout << stringV[1] << endl;

Output

A1
B1

Desired goal: I want to have each comma separated value added to a vector. Then, call out class constructors doing some inline typecasting for the last value from a string to an int.

Edit1 I understand my question is similar to The most elegant way to iterate the words of a string The main difference was that the solutions provided did not work well with a comma separated list, and as well iterating through an array/vector.

shell_surfer
  • 23
  • 1
  • 1
  • 4
  • 5
    Remember: a computer always does exactly what you tell it to do, and not what you want it to do. You told the computer you want to run a loop that takes each `studentData` string, puts it into a `std::istringstream`, uses `getline()` to extract everything in the `std::istringstream` until the first comma, then move on to the next `studentData` string, and that's exactly what your computer did. If you want your computer to extract everything in each string, separated by commas, then this is what you need to tell your computer to do. – Sam Varshavchik Oct 07 '18 at 15:11
  • 1
    Many examples here: https://stackoverflow.com/questions/236129/the-most-elegant-way-to-iterate-the-words-of-a-string?rq=1 I've settled on using boost::split, myself. –  Oct 07 '18 at 15:11
  • 1
    Search the internet for "c++ comma separated". There are a plethora of examples, including questions on StackOverflow. – Thomas Matthews Oct 07 '18 at 17:18

3 Answers3

9

Try this snippet:

int main()
{
    vector<string> sentences =
    { "A1,John,Smith,smithJ@mail.com,42",
        "B2,Jane,Doe,jd@gmailcom,121,2",
        "C3,Mickey,Mouse,mouseman@mail.com,20"
    };

    vector<string> results;

    for (auto words : sentences) {
        stringstream  ss(words);
        string str;
        while (getline(ss, str, ',')) {
            results.push_back(str);
        }
    }

    //display result
    for (auto word : results) {
        cout << word << '\n';
    }

    return 0;
}
seccpur
  • 4,996
  • 2
  • 13
  • 21
1

Try such function:

std::vector<std::string> split(const std::string& s, char delimiter)                                                                                                                          
{                                                                                                                                                                                             
   std::vector<std::string> splits;                                                                                                                                                           
   std::string split;                                                                                                                                                                         
   std::istringstream ss(s);                                                                                                                                                                  
   while (std::getline(ss, split, delimiter))                                                                                                                                                 
   {                                                                                                                                                                                          
      splits.push_back(split);                                                                                                                                                                
   }                                                                                                                                                                                          
   return splits;                                                                                                                                                                             
}

Then call it following:

auto userSplitData = split(userData[0], ',');
eXpl0it3R
  • 90
  • 2
  • 6
1

You are probably already fine with the proposed solutions, but if you want something more STL oriented, have a look at this:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{
    const std::vector<std::string> inputs = {
        "A1,John,Smith,smithJ@mail.com,42",
        "B2,Jane,Doe,jd@gmailcom,121,20",
        "C3,Mickey,Mouse,mouseman@mail.com,2"
    };
    std::vector<std::string> output;

    for(const auto& in : inputs)
    {
        auto it = std::begin(in);
        while (true)
        {
            auto commaPosition = std::find(it, std::end(in), ',');
            output.emplace_back(it, commaPosition);
            if (commaPosition == std::end(in))
            {
                break;
            }
            it = std::next(commaPosition);
        }
    }
    for (const auto& out : output)
    {
        std::cout << out  << std::endl;
    }
    return 0;
}
Paolo Irrera
  • 253
  • 1
  • 10
  • IMO you should get the `end` only once and then use that, rather than hoping the compiler optimises out the 2 calls per iteration; doing so does not decrease readability, in fact arguably the opposite. Anyway: A fun game here is to convert that `while` into a `for`, with all variables declared in the `for` statement and only a single statement in the body! pretty sure I've cracked it, but I'm not sure it serves readability, though it definitely serves my penchant for creating extremely complicated `for` statements. :P – underscore_d Oct 07 '18 at 21:04