Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stringUtils.cpp
Go to the documentation of this file.
1 /**
2  * @file stringUtils.cpp
3  * Contains definitions for string manipulation functions
4  * within Cantera.
5  */
6 // Copyright 2001 California Institute of Technology
7 
8 //@{
9 #include "cantera/base/ct_defs.h"
10 
11 #ifdef _MSC_VER
12 #define SNPRINTF _snprintf
13 #else
14 #define SNPRINTF snprintf
15 #endif
16 //@}
17 
20 #include "cantera/base/ctml.h"
21 
22 #include <sstream>
23 #include <cstdio>
24 
25 namespace Cantera
26 {
27 
28 std::string fp2str(const double x, const std::string& fmt)
29 {
30  char buf[64];
31  int n = SNPRINTF(buf, 63, fmt.c_str(), x);
32  if (n > 0) {
33  buf[63] = '\0';
34  return std::string(buf);
35  }
36  return std::string(" ");
37 }
38 
39 std::string int2str(const int n, const std::string& fmt)
40 {
41  char buf[30];
42  int m = SNPRINTF(buf, 30, fmt.c_str(), n);
43  if (m > 0) {
44  buf[29] = '\0';
45  return std::string(buf);
46  }
47  return std::string(" ");
48 }
49 
50 std::string int2str(const size_t n)
51 {
52  std::stringstream ss;
53  ss << n;
54  return ss.str();
55 }
56 
57 std::string vec2str(const vector_fp& v, const std::string& fmt,
58  const std::string& sep)
59 {
60  char buf[64];
61  std::stringstream o;
62  for (size_t i = 0; i < v.size(); i++) {
63  SNPRINTF(buf, 63, fmt.c_str(), v[i]);
64  o << v[i];
65  if (i != v.size() - 1) {
66  o << sep;
67  }
68  }
69  return o.str();
70 }
71 
72 
73 std::string lowercase(const std::string& s)
74 {
75  std::string lc(s);
76  for (size_t i = 0; i < s.size(); i++) {
77  lc[i] = (char) tolower(s[i]);
78  }
79  return lc;
80 }
81 
82 //! Return the position of the first printable character in the string
83 /*!
84  * @param s input string
85  * @return Returns an int representing the first printable string. If
86  * none returns the size of the string.
87  */
88 static int firstChar(const std::string& s)
89 {
90  int i;
91  int n = static_cast<int>(s.size());
92  for (i = 0; i < n; i++) {
93  if (s[i] != ' ' && isprint(s[i])) {
94  break;
95  }
96  }
97  return i;
98 }
99 
100 //! Return the position of the last printable character in the string
101 /*!
102  * @param s input string
103  * @return Returns an int representing the first printable string. If
104  * none returns -1.
105  */
106 static int lastChar(const std::string& s)
107 {
108  int i;
109  int n = static_cast<int>(s.size());
110  for (i = n-1; i >= 0; i--)
111  if (s[i] != ' ' && isprint(s[i])) {
112  break;
113  }
114  return i;
115 }
116 
117 std::string stripws(const std::string& s)
118 {
119  int ifirst = firstChar(s);
120  int ilast = lastChar(s);
121  return s.substr(ifirst, ilast - ifirst + 1);
122 }
123 
124 std::string stripnonprint(const std::string& s)
125 {
126  std::string ss = "";
127  for (size_t i = 0; i < s.size(); i++) {
128  if (isprint(s[i])) {
129  ss += s[i];
130  }
131  }
132  return ss;
133 }
134 
135 compositionMap parseCompString(const std::string& ss,
136  const std::vector<std::string>& names)
137 {
138  compositionMap x;
139  for (size_t k = 0; k < names.size(); k++) {
140  x[names[k]] = 0.0;
141  }
142 
143  size_t start = 0;
144  size_t stop = 0;
145  while (stop < ss.size()) {
146  size_t colon = ss.find(':', start);
147  if (colon == npos) {
148  break;
149  }
150  size_t valstart = ss.find_first_not_of(" \t\n", colon+1);
151  stop = ss.find_first_of(", ;\n\t", valstart);
152  std::string name = stripws(ss.substr(start, colon-start));
153  if (!names.empty() && x.find(name) == x.end()) {
154  throw CanteraError("parseCompString",
155  "unknown species '" + name + "'");
156  }
157  x[name] = fpValueCheck(ss.substr(valstart, stop-colon-1));
158  start = ss.find_first_not_of(", ;\n\t", stop+1);
159  }
160  if (stop != npos && !stripws(ss.substr(stop)).empty()) {
161  throw CanteraError("parseCompString", "Found non-key:value data "
162  "in composition string: '" + ss.substr(stop) + "'");
163  }
164  return x;
165 }
166 
167 void split(const std::string& ss, std::vector<std::string>& w)
168 {
169  warn_deprecated("split", "To be removed after Cantera 2.2.");
170  std::string s = ss;
171  std::string::size_type ibegin, iend;
172  std::string name, num, nm;
173  do {
174  ibegin = s.find_first_not_of(", ;\n\t");
175  if (ibegin != std::string::npos) {
176  s = s.substr(ibegin,s.size());
177  iend = s.find_first_of(", ;\n\t");
178  if (iend != std::string::npos) {
179  w.push_back(s.substr(0, iend));
180  s = s.substr(iend+1, s.size());
181  } else {
182  w.push_back(s.substr(0, s.size()));
183  return;
184  }
185  }
186  } while (s != "");
187 }
188 
189 int fillArrayFromString(const std::string& str,
190  doublereal* const a, const char delim)
191 {
192  warn_deprecated("fillArrayFromString", "To be removed after Cantera 2.2.");
193  std::string::size_type iloc;
194  int count = 0;
195  std::string num;
196  std::string s = str;
197  while (s.size() > 0) {
198  iloc = s.find(delim);
199  if (iloc > 0) {
200  num = s.substr(0, iloc);
201  s = s.substr(iloc+1,s.size());
202  } else {
203  num = s;
204  s = "";
205  }
206  a[count] = fpValueCheck(num);
207  count++;
208  }
209  return count;
210 }
211 
212 std::string getBaseName(const std::string& path)
213 {
214  warn_deprecated("getBaseName", "To be removed after Cantera 2.2.");
215  std::string file;
216  size_t idot = path.find_last_of('.');
217  size_t islash = path.find_last_of('/');
218  if (idot > 0 && idot < path.size()) {
219  if (islash > 0 && islash < idot) {
220  file = path.substr(islash+1, idot-islash-1);
221  } else {
222  file = path.substr(0,idot);
223  }
224  } else {
225  file = path;
226  }
227  return file;
228 }
229 
230 int intValue(const std::string& val)
231 {
232  return std::atoi(stripws(val).c_str());
233 }
234 
235 doublereal fpValue(const std::string& val)
236 {
237  doublereal rval;
238  std::stringstream ss(val);
239  ss.imbue(std::locale("C"));
240  ss >> rval;
241  return rval;
242 }
243 
244 doublereal fpValueCheck(const std::string& val)
245 {
246  std::string str = stripws(val);
247  if (str.empty()) {
248  throw CanteraError("fpValueCheck", "string has zero length");
249  }
250  int numDot = 0;
251  int numExp = 0;
252  char ch;
253  int istart = 0;
254  ch = str[0];
255  if (ch == '+' || ch == '-') {
256  istart = 1;
257  }
258  for (size_t i = istart; i < str.size(); i++) {
259  ch = str[i];
260  if (isdigit(ch)) {
261  } else if (ch == '.') {
262  numDot++;
263  if (numDot > 1) {
264  throw CanteraError("fpValueCheck",
265  "string has more than one .");
266  }
267  if (numExp > 0) {
268  throw CanteraError("fpValueCheck",
269  "string has decimal point in exponent");
270  }
271  } else if (ch == 'e' || ch == 'E' || ch == 'd' || ch == 'D') {
272  numExp++;
273  str[i] = 'E';
274  if (numExp > 1) {
275  throw CanteraError("fpValueCheck",
276  "string has more than one exp char");
277  }
278  ch = str[i+1];
279  if (ch == '+' || ch == '-') {
280  i++;
281  }
282  } else {
283  throw CanteraError("fpValueCheck",
284  "Trouble processing string, " + str);
285  }
286  }
287  return fpValue(str);
288 }
289 
290 std::string logfileName(const std::string& infile)
291 {
292  warn_deprecated("logfileName", "To be removed after Cantera 2.2.");
293  std::string logfile = getBaseName(infile);
294  logfile += ".log";
295  return logfile;
296 }
297 
298 std::string wrapString(const std::string& s, const int len)
299 {
300  int count=0;
301  std::string r;
302  for (size_t n = 0; n < s.size(); n++) {
303  if (s[n] == '\n') {
304  count = 0;
305  } else {
306  count++;
307  }
308  if (count > len && s[n] == ' ') {
309  r += "\n ";
310  count = 0;
311  }
312  r += s[n];
313  }
314  return r;
315 }
316 
317 std::string parseSpeciesName(const std::string& nameStr, std::string& phaseName)
318 {
319  std::string s = stripws(nameStr);
320  std::string::size_type ibegin, iend, icolon;
321  phaseName = "";
322  ibegin = s.find_first_not_of(" ;\n\t");
323  if (ibegin != std::string::npos) {
324  s = s.substr(ibegin,s.size());
325  icolon = s.find(':');
326  iend = s.find_first_of(" ;\n\t");
327  if (icolon != std::string::npos) {
328  phaseName = s.substr(0, icolon);
329  s = s.substr(icolon+1, s.size());
330  icolon = s.find(':');
331  if (icolon != std::string::npos) {
332  throw CanteraError("parseSpeciesName()", "two colons in name: " + nameStr);
333  }
334  }
335  if (iend != std::string::npos) {
336  throw CanteraError("parseSpeciesName()",
337  "Species name has \" ;/\n/\t\" in the middle of it: " + nameStr);
338  }
339  }
340  return s;
341 }
342 
343 doublereal strSItoDbl(const std::string& strSI)
344 {
345  std::vector<std::string> v;
346  tokenizeString(strSI, v);
347  doublereal fp = 1.0;
348  size_t n = v.size();
349  if (n > 2 || n < 1) {
350  throw CanteraError("strSItoDbl",
351  "number of tokens is too high");
352  } else if (n == 2) {
353  fp = toSI(v[1]);
354  }
355  doublereal val = fpValueCheck(v[0]);
356  return val * fp;
357 }
358 
359 //! Find the first white space in a string
360 /*!
361  * Returns the location of the first white space character in a string
362  *
363  * @param val Input string to be parsed
364  * @return In a size_type variable, return the location of the first white
365  * space character. Return npos if none is found
366  */
367 static std::string::size_type findFirstWS(const std::string& val)
368 {
369  std::string::size_type ibegin = std::string::npos;
370  int j = 0;
371  std::string::const_iterator i = val.begin();
372  for (; i != val.end(); i++) {
373  char ch = *i;
374  int ll = (int) ch;
375  if (isspace(ll)) {
376  ibegin = (std::string::size_type) j;
377  break;
378  }
379  j++;
380  }
381  return ibegin;
382 }
383 
384 //! Find the first non-white space in a string
385 /*!
386  * Returns the location of the first non-white space character in a string
387  *
388  * @param val Input string to be parsed
389  * @return In a size_type variable, return the location of the first
390  * nonwhite space character. Return npos if none is found
391  */
392 static std::string::size_type findFirstNotOfWS(const std::string& val)
393 {
394  std::string::size_type ibegin = std::string::npos;
395  int j = 0;
396  std::string::const_iterator i = val.begin();
397  for (; i != val.end(); i++) {
398  char ch = *i;
399  int ll = (int) ch;
400  if (!isspace(ll)) {
401  ibegin = (std::string::size_type) j;
402  break;
403  }
404  j++;
405  }
406  return ibegin;
407 }
408 
409 void tokenizeString(const std::string& oval,
410  std::vector<std::string>& v)
411 {
412  std::string val(oval);
413  std::string::size_type ibegin, iend;
414  v.clear();
415  while (1 > 0) {
416  ibegin = findFirstNotOfWS(val);
417  if (ibegin != std::string::npos) {
418  val = val.substr(ibegin,val.size());
419  iend = findFirstWS(val);
420  if (iend == std::string::npos) {
421  v.push_back(val);
422  break;
423  } else {
424  v.push_back(val.substr(0,iend));
425  val = val.substr(iend+1,val.size());
426  }
427  } else {
428  break;
429  }
430  }
431 }
432 
433 void copyString(const std::string& source, char* dest, size_t length)
434 {
435  const char* c_src = source.c_str();
436  size_t N = std::min(length, source.length()+1);
437  std::copy(c_src, c_src + N, dest);
438  if (length != 0) {
439  dest[length-1] = '\0';
440  }
441 }
442 
443 }
std::map< std::string, doublereal > compositionMap
Map connecting a string name with a double.
Definition: ct_defs.h:149
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
void split(const std::string &ss, std::vector< std::string > &w)
Parse a composition string into individual key:composition pairs.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:39
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
std::string vec2str(const vector_fp &v, const std::string &fmt, const std::string &sep)
Convert a vector to a string (separated by commas)
Definition: stringUtils.cpp:57
static int lastChar(const std::string &s)
Return the position of the last printable character in the string.
doublereal toSI(const std::string &unit)
Return the conversion factor to convert unit std::string 'unit' to SI units.
Definition: global.cpp:161
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
static std::string fmt(const std::string &r, size_t n)
This file contains definitions of terms that are used in internal routines and are unlikely to need m...
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:78
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:73
static std::string::size_type findFirstNotOfWS(const std::string &val)
Find the first non-white space in a string.
std::string getBaseName(const std::string &path)
Get the file name without the path or extension.
static std::string::size_type findFirstWS(const std::string &val)
Find the first white space in a string.
std::string stripws(const std::string &s)
Strip the leading and trailing white space from a string.
std::string logfileName(const std::string &infile)
Generate a logfile name based on an input file name.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
Definition: stringUtils.cpp:28
void tokenizeString(const std::string &oval, std::vector< std::string > &v)
This function separates a string up into tokens according to the location of white space...
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
int fillArrayFromString(const std::string &str, doublereal *const a, const char delim)
Interpret a string as a list of floats, and convert it to a vector of floats.
std::string parseSpeciesName(const std::string &nameStr, std::string &phaseName)
Parse a name string, separating out the phase name from the species name.
std::string wrapString(const std::string &s, const int len)
Line wrap a string via a copy operation.
int intValue(const std::string &val)
Translate a string into one integer value.
compositionMap parseCompString(const std::string &ss, const std::vector< std::string > &names)
Parse a composition string into a map consisting of individual key:composition pairs.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:157
Contains declarations for string manipulation functions within Cantera.
void copyString(const std::string &source, char *dest, size_t length)
Copy the contents of a std::string into a char array of a given length.
doublereal strSItoDbl(const std::string &strSI)
Interpret one or two token string as a single double.
std::string stripnonprint(const std::string &s)
Strip non-printing characters wherever they are.
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
static int firstChar(const std::string &s)
Return the position of the first printable character in the string.
Definition: stringUtils.cpp:88