One common usage when processing text is to see it as a series of columns,
like those of a system's log, to extract one or more and use them
in different ways while discarding others. Surprisingly, C++ strings
lack a method to split themselves. The alternative (strtok()) is not really
a C++ solution, since it involves using C arrays. Another problem is its
low-level nature: the user must send a pointer to help
strtok().
In this example I have derived a class splitstring from
string. If you have a splitstring and you want to use it as a string, you
can, because it is one. But if you need to split the string, you can split
it too. The output of running method split() of a splitstring is a vector
of strings. This is more similar to high level languages where strings have
a split() method.
Possible expansions would be methods that split based on regular expressions
or constant strings.
To use as part of a larger project, the class declaration should be placed
in a separate file to be included in this and your code (but I am assuming
you already know that). The define MAIN directive should be commented out as well./p>
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 
 | // Class splitstring which adds method split()
// define MAIN if this is a standalone program
#define MAIN 1
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class splitstring : public string {
    vector<string> flds;
public:
    splitstring(char *s) : string(s) { };
    vector<string>& split(char delim, int rep=0);
};
// split: receives a char delimiter; returns a vector of strings
// By default ignores repeated delimiters, unless argument rep == 1.
vector<string>& splitstring::split(char delim, int rep) {
    if (!flds.empty()) flds.clear();  // empty vector if necessary
    string work = data();
    string buf = "";
    int i = 0;
    while (i < work.length()) {
        if (work[i] != delim)
            buf += work[i];
        else if (rep == 1) {
            flds.push_back(buf);
            buf = "";
        } else if (buf.length() > 0) {
            flds.push_back(buf);
            buf = "";
        }
        i++;
    }
    if (!buf.empty())
        flds.push_back(buf);
    return flds;
}
#ifdef MAIN
main()
{
    // we define a string
    splitstring s("Humpty Dumpty sat on a wall.   Humpty Dumpty had a great fall");
    cout << s << endl;
    // splits and displays the vector of strings
    vector<string> flds = s.split(' ');
    for (int k = 0; k < flds.size(); k++)
        cout << k << " => " << flds[k] << endl;
    // now taking account of repeated delimiters
    cout << endl << "with repeated delimiters:" << endl;
    vector<string> flds2 = s.split(' ', 1);
    for (int k = 0; k < flds2.size(); k++)
        cout << k << " => " << flds2[k] << endl;
}
#endif
 |  |