str.hh

Go to the documentation of this file.
00001 #ifndef STR_HH
00002 #define STR_HH
00003 
00004 #include <string>
00005 #include <vector>
00006 #include <stdexcept>
00007 
00008 #include <stdio.h>
00009 #include <stdarg.h>
00010 #include <stdlib.h>
00011 #include <math.h>
00012 
00017 namespace str {
00018 
00024   inline std::string fmt(size_t size, const char *fmt, ...)
00025   {
00026     va_list ap;
00027     va_start(ap, fmt);
00028     char *buf = new char[size];
00029     vsnprintf(buf, size, fmt, ap);
00030     va_end(ap);
00031 
00032     std::string str(buf);
00033     delete[] buf;
00034     return str;
00035   }
00036 
00041   inline void clean(std::string &str, const char *chars = " \n\t")
00042   {
00043     int i;
00044 
00045     // Clean trailing chars
00046     //
00047     for (i = str.length(); i > 0; i--)
00048       if (!strchr(chars, str[i - 1]))
00049         break;
00050     str.erase(i);
00051 
00052     // Clean leading chars
00053     //
00054     for (i = 0; i < (int)str.length(); i++)
00055       if (!strchr(chars, str[i]))
00056         break;
00057     str.erase(0, i);
00058   }
00059 
00065   inline std::string cleaned(const std::string &str, 
00066                              const char *chars = " \n\t")
00067   {
00068     std::string ret = str;
00069     clean(ret, chars);
00070     return ret;
00071   }
00072 
00084   inline std::vector<std::string>
00085   split(const std::string &str, const char *delims, bool group, 
00086         unsigned int num_fields = 0)
00087   {
00088     std::vector<std::string> fields;
00089     size_t begin = 0;
00090     size_t end = 0;
00091 
00092     fields.clear();
00093     bool delim_pending = false;
00094     while (begin < str.length()) {
00095       // If 'fields' fields was requested and, this is the last field,
00096       // include the rest.
00097       if (num_fields > 0 && fields.size() == num_fields - 1) {
00098         delim_pending = false;
00099         fields.push_back(str.substr(begin));
00100         break;
00101       }
00102 
00103       // Find the string before the next delim
00104       delim_pending = false;
00105       while (end < str.length()) {
00106         if (strchr(delims, str[end])) {
00107           delim_pending = true;
00108           break;
00109         }
00110         end++;
00111       }
00112       fields.push_back(str.substr(begin, end - begin));
00113 
00114       // Eat the delim or group of delims
00115       end++;
00116       if (group)
00117         while (end < str.length() && strchr(delims, str[end]))
00118           end++;
00119 
00120       begin = end;
00121     }
00122 
00123     if (delim_pending)
00124       fields.push_back("");
00125 
00126     return fields;
00127   }
00128 
00139   inline long str2long(const std::string &str, int base = 10)
00140   {
00141     char *endptr;
00142     const char *c_str = str.c_str();
00143 
00144     long value = strtol(c_str, &endptr, base);
00145     if (value == LONG_MIN || value == LONG_MAX)
00146       throw std::out_of_range("str::str2long: argument out of range");
00147     if (*c_str == '\0' || *endptr != '\0')
00148       throw std::invalid_argument("str::str2long: invalid string");
00149 
00150     return value;
00151   }
00152 
00163   inline unsigned long str2ulong(const std::string &str, int base = 10)
00164   {
00165     char *endptr;
00166     const char *c_str = str.c_str();
00167 
00168     unsigned long value = strtoul(c_str, &endptr, base);
00169     if (value == ULONG_MAX)
00170       throw std::out_of_range("str::str2ulong: argument out of range");
00171     if (*c_str == '\0' || *endptr != '\0')
00172       throw std::invalid_argument("str::str2ulong: invalid string");
00173 
00174     return value;
00175   }
00176 
00185   inline float str2float(const std::string &str)
00186   {
00187     char *endptr;
00188     const char *c_str = str.c_str();
00189 
00190     float value = strtof(c_str, &endptr);
00191     if (value == -HUGE_VALF || value == HUGE_VALF)
00192       throw std::out_of_range("str::str2float: argument out of range");
00193     if (*c_str == '\0' || *endptr != '\0')
00194       throw std::invalid_argument("str::str2float: invalid string");
00195 
00196     return value;
00197   }
00198 
00199 
00205   template <class T>
00206   std::vector<T> long_vec(const std::string &str)
00207   {
00208     std::vector<std::string> str_vec(
00209       str::split(str::cleaned(str), " \t\n", true));
00210     std::vector<T> vec(str_vec.size());
00211     for (size_t i = 0; i < str_vec.size(); i++)
00212       vec[i] = str::str2long(str_vec[i]);
00213     return vec;
00214   }
00215 
00221   inline std::vector<float> float_vec(const std::string &str)
00222   {
00223     std::vector<std::string> str_vec(
00224       str::split(str::cleaned(str), " \t\n", true));
00225     std::vector<float> vec(str_vec.size());
00226     for (size_t i = 0; i < str_vec.size(); i++)
00227       vec[i] = str::str2float(str_vec[i]);
00228     return vec;
00229   }
00230 
00236   inline std::string chomped(const std::string &str, const char *chars = "\n")
00237   {
00238     if (!str.empty() && strchr(chars, str[str.length() - 1]))
00239       return str.substr(0, str.length() - 1);
00240     return str;
00241   }
00242 
00248   inline std::string &chomp(std::string &str, const char *chars = "\n")
00249   {
00250     if (!str.empty() && strchr(chars, str[str.length() - 1]))
00251       str.erase(str.end() - 1);
00252     return str;
00253   }
00254 
00262   inline bool 
00263   read_line(std::string &str, FILE *file = stdin, bool do_chomp = false)
00264   {
00265     char *ptr;
00266     char buf[4096];
00267 
00268     str.erase();
00269     while (1) {
00270       ptr = fgets(buf, 4096, file);
00271       if (!ptr)
00272         break;
00273 
00274       str.append(buf);
00275       if (str[str.length() - 1] == '\n') {
00276         break;
00277       }
00278     }
00279 
00280     if (ferror(file) || str.length() == 0)
00281       return false;
00282 
00283     if (do_chomp)
00284       chomp(str, "\n");
00285 
00286     return true;
00287   }
00288 
00289 
00290 };
00291 
00292 #endif /* STR_HH */

Generated on Mon Jan 8 15:51:03 2007 for bit by  doxygen 1.4.6