1 /** 2 * @file string_manip.cpp 3 * std::string helpers 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Philippe Elie 9 * @author John Levon 10 */ 11 12 #include <sstream> 13 #include <iomanip> 14 15 #include <cstdlib> 16 #include <cmath> 17 18 #include "string_manip.h" 19 20 using namespace std; 21 22 23 string erase_to_last_of(string const & str, char ch) 24 { 25 string result = str; 26 string::size_type pos = result.find_last_of(ch); 27 if (pos != string::npos) 28 result.erase(0, pos + 1); 29 30 return result; 31 } 32 33 34 string split(string & s, char c) 35 { 36 string::size_type i = s.find_first_of(c); 37 if (i == string::npos) 38 return string(); 39 40 string const tail = s.substr(i + 1); 41 s = s.substr(0, i); 42 return tail; 43 } 44 45 46 bool is_prefix(string const & s, string const & prefix) 47 { 48 // gcc 2.95 and below don't have this 49 // return s.compare(0, prefix.length(), prefix) == 0; 50 return s.find(prefix) == 0; 51 } 52 53 54 vector<string> separate_token(string const & str, char sep) 55 { 56 vector<string> result; 57 string next; 58 59 for (size_t pos = 0 ; pos != str.length() ; ++pos) { 60 char ch = str[pos]; 61 if (ch == '\\') { 62 if (pos < str.length() - 1 && str[pos + 1] == sep) { 63 ++pos; 64 next += sep; 65 } else { 66 next += '\\'; 67 } 68 } else if (ch == sep) { 69 result.push_back(next); 70 // some stl lacks string::clear() 71 next.erase(next.begin(), next.end()); 72 } else { 73 next += ch; 74 } 75 } 76 77 if (!next.empty()) 78 result.push_back(next); 79 80 return result; 81 } 82 83 84 string ltrim(string const & str, string const & totrim) 85 { 86 string result(str); 87 88 return result.erase(0, result.find_first_not_of(totrim)); 89 } 90 91 92 string rtrim(string const & str, string const & totrim) 93 { 94 string result(str); 95 96 return result.erase(result.find_last_not_of(totrim) + 1); 97 } 98 99 100 string trim(string const & str, string const & totrim) 101 { 102 return rtrim(ltrim(str, totrim), totrim); 103 } 104 105 106 string const 107 format_percent(double value, size_t int_width, size_t fract_width, bool showpos) 108 { 109 ostringstream os; 110 111 if (value == 0.0) 112 return string(int_width + fract_width, ' ') + "0"; 113 114 if (showpos) 115 os.setf(ios::showpos); 116 117 if (fabs(value) > .001) { 118 // os << fixed << value unsupported by gcc 2.95 119 os.setf(ios::fixed, ios::floatfield); 120 os << setw(int_width + fract_width + 1) 121 << setprecision(fract_width) << value; 122 } else { 123 // os << scientific << value unsupported by gcc 2.95 124 os.setf(ios::scientific, ios::floatfield); 125 os << setw(int_width + fract_width + 1) 126 // - 3 to count exponent part 127 << setprecision(fract_width - 3) << value; 128 } 129 130 string formatted = os.str(); 131 if (is_prefix(formatted, "100.")) 132 formatted.erase(formatted.size() - 1); 133 return formatted; 134 } 135 136 137 template <> 138 unsigned int op_lexical_cast<unsigned int, string>(string const & str) 139 { 140 char* endptr; 141 142 // 2.91.66 fix 143 unsigned long ret = 0; 144 ret = strtoul(str.c_str(), &endptr, 0); 145 if (*endptr) 146 throw invalid_argument("op_lexical_cast(\""+ str +"\")"); 147 return ret; 148 } 149