#include #include #include #include #include #include using namespace std; namespace { /** * This function splits the string s based on the * delimiters in delim using the standard string * tokenizer strtok_r(). The results are returned as * a vector of strings. * * @param[in] s string to tokenize * @param[in] delim list of characters used as delimiters * @return tokenized strings */ vector split(const string& s, const string& delim) { vector rv; char* sdup = NULL; char* tmp = NULL; char* next = NULL; try { // strtok_r() inserts '\0' characters in the input string // so we need to make a copy to avoid damaging the // original. sdup = strdup(s.c_str()); if (!sdup) { throw runtime_error("out of memory"); } // Split the string. Note that on the first call to // strtok_r(), we have to pass in the string we want to // split. On subsequent calls, we have to pass in NULL as // the first parameter instead. next = strtok_r(sdup, delim.c_str(), &tmp); while (next != NULL) { rv.push_back(next); next = strtok_r(NULL, delim.c_str(), &tmp); } } catch (...) { // Clean up if an exception is thrown. if (sdup) { free(sdup); } // Rethrow the exception. throw; } // Clean up for normal termination. if (sdup) { free(sdup); } return rv; } } int main(int argc, char* argv[]) { int rv = 0; try { string line; while (getline(cin, line)) { cout << "line = \"" << line << "\"" << endl; vector v = split(line, " \t\n\f"); for( unsigned i = 0 ; i < v.size() ; ++i ) { cout << " " << i << ": \"" << v[i] << "\"" << endl; } } } catch (const exception& e) { cerr << e.what() << endl; rv = 1; } return rv; }