Cantera  2.1.2
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/global.h"
21 #include "cantera/base/ctml.h"
22 
23 #include <sstream>
24 #include <cstdio>
25 
26 namespace Cantera
27 {
28 
29 std::string fp2str(const double x, const std::string& fmt)
30 {
31  char buf[64];
32  int n = SNPRINTF(buf, 63, fmt.c_str(), x);
33  if (n > 0) {
34  buf[63] = '\0';
35  return std::string(buf);
36  }
37  return std::string(" ");
38 }
39 
40 std::string int2str(const int n, const std::string& fmt)
41 {
42  char buf[30];
43  int m = SNPRINTF(buf, 30, fmt.c_str(), n);
44  if (m > 0) {
45  buf[29] = '\0';
46  return std::string(buf);
47  }
48  return std::string(" ");
49 }
50 
51 std::string int2str(const size_t n)
52 {
53  std::stringstream ss;
54  ss << n;
55  return ss.str();
56 }
57 
58 std::string lowercase(const std::string& s)
59 {
60  int n = static_cast<int>(s.size());
61  std::string lc(s);
62  for (int i = 0; i < n; i++) {
63  lc[i] = (char) tolower(s[i]);
64  }
65  return lc;
66 }
67 
68 //! Return the position of the first printable character in the string
69 /*!
70  * @param s input string
71  * @return Returns an int representing the first printable string. If
72  * none returns the size of the string.
73  */
74 static int firstChar(const std::string& s)
75 {
76  int i;
77  int n = static_cast<int>(s.size());
78  for (i = 0; i < n; i++) {
79  if (s[i] != ' ' && isprint(s[i])) {
80  break;
81  }
82  }
83  return i;
84 }
85 
86 //! Return the position of the last printable character in the string
87 /*!
88  * @param s input string
89  * @return Returns an int representing the first printable string. If
90  * none returns -1.
91  */
92 static int lastChar(const std::string& s)
93 {
94  int i;
95  int n = static_cast<int>(s.size());
96  for (i = n-1; i >= 0; i--)
97  if (s[i] != ' ' && isprint(s[i])) {
98  break;
99  }
100  return i;
101 }
102 
103 std::string stripws(const std::string& s)
104 {
105  int ifirst = firstChar(s);
106  int ilast = lastChar(s);
107  return s.substr(ifirst, ilast - ifirst + 1);
108 }
109 
110 std::string stripnonprint(const std::string& s)
111 {
112  int i;
113  int n = static_cast<int>(s.size());
114  std::string ss = "";
115  for (i = 0; i < n; i++) {
116  if (isprint(s[i])) {
117  ss += s[i];
118  }
119  }
120  return ss;
121 }
122 
123 compositionMap parseCompString(const std::string& ss,
124  const std::vector<std::string>& names)
125 {
126  compositionMap x;
127  for (size_t k = 0; k < names.size(); k++) {
128  x[names[k]] = 0.0;
129  }
130  std::string s = ss;
131  std::string num;
132  do {
133  size_t ibegin = s.find_first_not_of(", ;\n\t");
134  if (ibegin != std::string::npos) {
135  s = s.substr(ibegin,s.size());
136  size_t icolon = s.find(':');
137  size_t iend = s.find_first_of(", ;\n\t");
138  //icomma = s.find(',');
139  if (icolon != std::string::npos) {
140  std::string name = stripws(s.substr(0, icolon));
141  if (iend != std::string::npos) {
142  num = s.substr(icolon+1, iend-icolon-1);
143  s = s.substr(iend+1, s.size());
144  } else {
145  num = s.substr(icolon+1, s.size());
146  s = "";
147  }
148  if (x.find(name) == x.end()) {
149  throw CanteraError("parseCompString",
150  "unknown species " + name);
151  }
152  x[name] = fpValueCheck(num);
153  } else {
154  s = "";
155  }
156  }
157  } while (s != "");
158  return x;
159 }
160 
161 void split(const std::string& ss, std::vector<std::string>& w)
162 {
163  std::string s = ss;
164  std::string::size_type ibegin, iend;
165  std::string name, num, nm;
166  do {
167  ibegin = s.find_first_not_of(", ;\n\t");
168  if (ibegin != std::string::npos) {
169  s = s.substr(ibegin,s.size());
170  iend = s.find_first_of(", ;\n\t");
171  if (iend != std::string::npos) {
172  w.push_back(s.substr(0, iend));
173  s = s.substr(iend+1, s.size());
174  } else {
175  w.push_back(s.substr(0, s.size()));
176  return;
177  }
178  }
179  } while (s != "");
180 }
181 
182 int fillArrayFromString(const std::string& str,
183  doublereal* const a, const char delim)
184 {
185  std::string::size_type iloc;
186  int count = 0;
187  std::string num;
188  std::string s = str;
189  while (s.size() > 0) {
190  iloc = s.find(delim);
191  if (iloc > 0) {
192  num = s.substr(0, iloc);
193  s = s.substr(iloc+1,s.size());
194  } else {
195  num = s;
196  s = "";
197  }
198  a[count] = fpValueCheck(num);
199  count++;
200  }
201  return count;
202 }
203 
204 std::string getBaseName(const std::string& path)
205 {
206  std::string file;
207  size_t idot = path.find_last_of('.');
208  size_t islash = path.find_last_of('/');
209  if (idot > 0 && idot < path.size()) {
210  if (islash > 0 && islash < idot) {
211  file = path.substr(islash+1, idot-islash-1);
212  } else {
213  file = path.substr(0,idot);
214  }
215  } else {
216  file = path;
217  }
218  return file;
219 }
220 
221 int intValue(const std::string& val)
222 {
223  return std::atoi(stripws(val).c_str());
224 }
225 
226 doublereal fpValue(const std::string& val)
227 {
228  doublereal rval;
229  std::stringstream ss(val);
230  ss.imbue(std::locale("C"));
231  ss >> rval;
232  return rval;
233 }
234 
235 doublereal fpValueCheck(const std::string& val)
236 {
237  std::string str = stripws(val);
238  if (str.empty()) {
239  throw CanteraError("fpValueCheck", "string has zero length");
240  }
241  int numDot = 0;
242  int numExp = 0;
243  char ch;
244  int istart = 0;
245  ch = str[0];
246  if (ch == '+' || ch == '-') {
247  istart = 1;
248  }
249  for (size_t i = istart; i < str.size(); i++) {
250  ch = str[i];
251  if (isdigit(ch)) {
252  } else if (ch == '.') {
253  numDot++;
254  if (numDot > 1) {
255  throw CanteraError("fpValueCheck",
256  "string has more than one .");
257  }
258  } else if (ch == 'e' || ch == 'E' || ch == 'd' || ch == 'D') {
259  numExp++;
260  str[i] = 'E';
261  if (numExp > 1) {
262  throw CanteraError("fpValueCheck",
263  "string has more than one exp char");
264  }
265  ch = str[i+1];
266  if (ch == '+' || ch == '-') {
267  i++;
268  }
269  } else {
270  throw CanteraError("fpValueCheck",
271  "Trouble processing string, " + str);
272  }
273  }
274  return fpValue(str);
275 }
276 
277 std::string logfileName(const std::string& infile)
278 {
279  std::string logfile = getBaseName(infile);
280  logfile += ".log";
281  return logfile;
282 }
283 
284 std::string wrapString(const std::string& s, const int len)
285 {
286  int count=0;
287  std::string r;
288  for (size_t n = 0; n < s.size(); n++) {
289  if (s[n] == '\n') {
290  count = 0;
291  } else {
292  count++;
293  }
294  if (count > len && s[n] == ' ') {
295  r += "\n ";
296  count = 0;
297  }
298  r += s[n];
299  }
300  return r;
301 }
302 
303 std::string parseSpeciesName(const std::string& nameStr, std::string& phaseName)
304 {
305  std::string s = stripws(nameStr);
306  std::string::size_type ibegin, iend, icolon;
307  phaseName = "";
308  ibegin = s.find_first_not_of(" ;\n\t");
309  if (ibegin != std::string::npos) {
310  s = s.substr(ibegin,s.size());
311  icolon = s.find(':');
312  iend = s.find_first_of(" ;\n\t");
313  if (icolon != std::string::npos) {
314  phaseName = s.substr(0, icolon);
315  s = s.substr(icolon+1, s.size());
316  icolon = s.find(':');
317  if (icolon != std::string::npos) {
318  throw CanteraError("parseSpeciesName()", "two colons in name: " + nameStr);
319  }
320  }
321  if (iend != std::string::npos) {
322  throw CanteraError("parseSpeciesName()",
323  "Species name has \" ;/\n/\t\" in the middle of it: " + nameStr);
324  }
325  }
326  return s;
327 }
328 
329 int stripLTWScstring(char str[])
330 {
331  warn_deprecated("stripLTWScstring");
332  int i = 0, j = 0;
333  char ch;
334  const char COM_CHAR='\0';
335  /*
336  * Quick Returns
337  */
338  if ((str == 0) || (str[0] == '\0')) {
339  return 0;
340  }
341 
342  /* Find first non-space character character */
343  while (((ch = str[i]) != '\0') && isspace(ch)) {
344  i++;
345  }
346 
347  /*
348  * Move real part of str to the front by copying the string
349  * - Comments are handled here, by terminating the copy at the
350  * first comment indicator, and inserting the null character at
351  * that point.
352  */
353 
354  while ((ch = str[j+i]) != '\0' &&
355  (ch != COM_CHAR)) {
356  str[j] = ch;
357  j++;
358  }
359  str[j] = '\0';
360  j--;
361  /* Remove trailing white space by inserting a null character */
362  while ((j != -1) && isspace(str[j])) {
363  j--;
364  }
365  j++;
366  str[j] = '\0';
367  return j;
368 }
369 
370 doublereal strSItoDbl(const std::string& strSI)
371 {
372  std::vector<std::string> v;
373  tokenizeString(strSI, v);
374  doublereal fp = 1.0;
375  size_t n = v.size();
376  if (n > 2 || n < 1) {
377  throw CanteraError("strSItoDbl",
378  "number of tokens is too high");
379  } else if (n == 2) {
380  fp = toSI(v[1]);
381  }
382  doublereal val = fpValueCheck(v[0]);
383  return val * fp;
384 }
385 
386 //! Find the first white space in a string
387 /*!
388  * Returns the location of the first white space character in a string
389  *
390  * @param val Input string to be parsed
391  * @return In a size_type variable, return the location of the first white
392  * space character. Return npos if none is found
393  */
394 static std::string::size_type findFirstWS(const std::string& val)
395 {
396  std::string::size_type ibegin = std::string::npos;
397  int j = 0;
398  std::string::const_iterator i = val.begin();
399  for (; i != val.end(); i++) {
400  char ch = *i;
401  int ll = (int) ch;
402  if (isspace(ll)) {
403  ibegin = (std::string::size_type) j;
404  break;
405  }
406  j++;
407  }
408  return ibegin;
409 }
410 
411 //! Find the first non-white space in a string
412 /*!
413  * Returns the location of the first non-white space character in a string
414  *
415  * @param val Input string to be parsed
416  * @return In a size_type variable, return the location of the first
417  * nonwhite space character. Return npos if none is found
418  */
419 static std::string::size_type findFirstNotOfWS(const std::string& val)
420 {
421  std::string::size_type ibegin = std::string::npos;
422  int j = 0;
423  std::string::const_iterator i = val.begin();
424  for (; i != val.end(); i++) {
425  char ch = *i;
426  int ll = (int) ch;
427  if (!isspace(ll)) {
428  ibegin = (std::string::size_type) j;
429  break;
430  }
431  j++;
432  }
433  return ibegin;
434 }
435 
436 void tokenizeString(const std::string& oval,
437  std::vector<std::string>& v)
438 {
439  std::string val(oval);
440  std::string::size_type ibegin, iend;
441  v.clear();
442  while (1 > 0) {
443  ibegin = findFirstNotOfWS(val);
444  if (ibegin != std::string::npos) {
445  val = val.substr(ibegin,val.size());
446  iend = findFirstWS(val);
447  if (iend == std::string::npos) {
448  v.push_back(val);
449  break;
450  } else {
451  v.push_back(val.substr(0,iend));
452  val = val.substr(iend+1,val.size());
453  }
454  } else {
455  break;
456  }
457  }
458 }
459 
460 void copyString(const std::string& source, char* dest, size_t length)
461 {
462  const char* c_src = source.c_str();
463  size_t N = std::min(length, source.length()+1);
464  std::copy(c_src, c_src + N, dest);
465  if (length != 0) {
466  dest[length-1] = '\0';
467  }
468 }
469 
470 }
std::map< std::string, doublereal > compositionMap
Map connecting a string name with a double.
Definition: ct_defs.h:162
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:40
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
static int lastChar(const std::string &s)
Return the position of the last printable character in the string.
Definition: stringUtils.cpp:92
doublereal toSI(const std::string &unit)
Return the conversion factor to convert unit std::string 'unit' to SI units.
Definition: global.cpp:196
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:173
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:76
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:58
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, HTML_logs (see Input File Handling, Diagnostic Output, Writing messages to the screen and Writing HTML Logfiles).
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.
int stripLTWScstring(char str[])
Routine strips off white space from a c character string.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
Definition: stringUtils.cpp:29
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:68
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.
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.
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:74