0

I'm relatively new at c++ programming so bear with me if I make any common mistakes.

I have a string that looks like this:

String str = "[abc, abcde, lkejs, abde], [123, 456, 7890]"

I wish to store each of those values into a vector such that it looks something like:

abc abcde lkejs abde 123 456 7890

I've read up on and tried using Boost tokenizer but I'm restricted from installing new libraries into the operating system which this code is supposed to be run.

I've also tried strtok() but that just confuses me even further as it converts my entire string into chars.

Looking through http://www.cplusplus.com/faq/sequences/strings/split/#boost-split , I probably would be better off using string::find_first_of() but the examples available there aren't doing much in helping me understand how it works.

Can anyone help me understand the syntax of string::find_first_of() better or is there a better way of splitting strings without the need to install additional libraries like boost does?

yxt
  • 17
  • 4

1 Answers1

2

The first part is to remove the brackets and the comma, for this std::string::erase with std::remove_if may be good.

str.erase(std::remove_if(std::begin(str), std::end(str), [](const char& ch){
              return ch == '[' || ch == ']' || ch == ',';
          }), std::end(str));

Then you need to tokenize the remaining string, which again you can use std::istringstream, together with the standard algorithm std::copy, and the iterator helpers std::istream_iterator and std::back_inserter:

std::vector<std::string> v;
std::istringstream iss(str);

std::copy(std::istream_iterator<std::string>(iss),
          std::istream_iterator<std::string>(),
          std::back_inserter(v));

Note: I used a C++11 lambda expression in the std::remove_if call. It can simply be replaced by a normal function if you don't have a C++11 capable compiler.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    `remove_if` doesn't erase, but it shifts and returns the iterator at the end of the new range. The resulting str will be "abc abcde lkejs abde 123 456 7890456, 7890]". This may cause a surprise when tokenizing in the next steps. – Phillip Kinkade Nov 14 '13 at 08:38
  • @PhillipKinkade Okay, noted. Updated answer to do what the example in the `remove_if` reference does. – Some programmer dude Nov 14 '13 at 08:50
  • Though clever, I would be very afraid of getting `[123,456]` in input since this method would turn it into `123456`. Instead of `remove_if` I would propose a `for (char& c: str) { if (c == '[' ...) c = ' '; }` solution... see it [on coliru](http://coliru.stacked-crooked.com/a/c67cede4b1dc07af) – Matthieu M. Nov 14 '13 at 10:35
  • @MatthieuM. Maybe use [`std::replace_if`](http://en.cppreference.com/w/cpp/algorithm/replace) to replace those special characters with a space? – Some programmer dude Nov 14 '13 at 10:42
  • @JoachimPileborg: WoW! I did not even know this existed! Yeah, in this case `replace_if` sounds perfect :) – Matthieu M. Nov 14 '13 at 10:44
  • Hi, thanks for the help, I do have a few problems which I encountered while trying out what you have said above, I get a compilation error of 'begin' was not declared in this scope and 'end' was not declared in this scope. – yxt Nov 16 '13 at 06:42
  • @yxt Use `str.begin()` and `str.end()` instead. – Some programmer dude Nov 16 '13 at 10:40