// StringParser // A StringParser object is constructed from a string. Successive calls // to the getNextField member function extract the next field from the // string, returning true if it got one and false if there was no next field. // Fields are separated by blank, tab, carriage return, or newline, and // may be surrounded by single quotes, which are stripped off in the // extracted field. Two consecutive single quotes in a quoted field are // converted to one. // // Here's an example of what it does: // StringParser parser(" abc 'def ghi' 'Don''t cry' '' jk "); // string s; // assert(parser.getNextField(s) && s == "abc"); // assert(parser.getNextField(s) && s == "def ghi"); // assert(parser.getNextField(s) && s == "Don't cry"); // assert(parser.getNextField(s) && s == ""); // assert(parser.getNextField(s) && s == "jk"); // assert(!parser.getNextField(s)); #include class StringParser { public: StringParser(std::string text = "") { setString(text); } void setString(std::string text) { m_text = text; m_start = 0; } bool getNextField(std::string& field); private: std::string m_text; size_t m_start; }; bool StringParser::getNextField(std::string& fieldText) { m_start = m_text.find_first_not_of(" \t\r\n", m_start); if (m_start == std::string::npos) { m_start = m_text.size(); fieldText = ""; return false; } if (m_text[m_start] != '\'') { size_t end = m_text.find_first_of(" \t\r\n", m_start+1); fieldText = m_text.substr(m_start, end-m_start); m_start = end; return true; } fieldText = ""; for (;;) { m_start++; size_t end = m_text.find('\'', m_start); fieldText += m_text.substr(m_start, end-m_start); m_start = (end != std::string::npos ? end+1 : m_text.size()); if (m_start == m_text.size() || m_text[m_start] != '\'') break; fieldText += '\''; } return true; }