# HG changeset patch # User John W. Eaton # Date 1324422367 18000 # Node ID b6eeeb67fa3f120ec02aa0b36b0500fca69ec49c # Parent 9aff66860e0313f3a4f3de2ce44c69196064199e str2double: return NaN for things like "1 2 3 4" (bug #34713). * str2double.cc (single_num, extract_num): Skip spaces as needed. (str2double1): Don't skip all spaces. diff -r 9aff66860e03 -r b6eeeb67fa3f src/DLD-FUNCTIONS/str2double.cc --- a/src/DLD-FUNCTIONS/str2double.cc Tue Dec 20 17:08:42 2011 -0500 +++ b/src/DLD-FUNCTIONS/str2double.cc Tue Dec 20 18:06:07 2011 -0500 @@ -46,6 +46,14 @@ single_num (std::istringstream& is, double& num) { char c = is.peek (); + + // Skip spaces. + while (isspace (c)) + { + is.get (); + c = is.peek (); + } + if (c == 'I') { // It's infinity. @@ -93,6 +101,14 @@ have_sign = imag = false; char c = is.peek (); + + // Skip leading spaces. + while (isspace (c)) + { + is.get (); + c = is.peek (); + } + bool negative = false; // Accept leading sign. @@ -104,12 +120,27 @@ have_sign = true; } + // Skip spaces after sign. + while (isspace (c)) + { + is.get (); + c = is.peek (); + } + // It's i*num or just i. if (is_imag_unit (c)) { c = is.get (); imag = true; char cn = is.peek (); + + // Skip spaces after imaginary unit. + while (isspace (cn)) + { + is.get (); + cn = is.peek (); + } + if (cn == '*') { // Multiplier follows, we extract it as a number. @@ -126,14 +157,31 @@ if (is.good ()) { c = is.peek (); + + // Skip spaces after number. + while (isspace (c)) + { + is.get (); + c = is.peek (); + } + if (c == '*') { is.get (); - c = is.get (); + c = is.peek (); + + // Skip spaces after operator. + while (isspace (c)) + { + is.get (); + c = is.peek (); + } + if (is_imag_unit (c)) { imag = true; - is.peek (); + is.get (); + is.peek (); // Sets eof bit. } else is.setstate (std::ios::failbit); // indicate that read has failed. @@ -142,7 +190,7 @@ { imag = true; is.get (); - is.peek (); + is.peek (); // Sets eof bit. } } } @@ -181,14 +229,12 @@ std::string str = str_arg; + // FIXME -- removing all commas does too much... std::string::iterator se = str.end (); - - // Remove commas (thousand separators) and spaces. se = std::remove (str.begin (), se, ','); - se = std::remove (str.begin (), se, ' '); str.erase (se, str.end ()); + std::istringstream is (str); - std::istringstream is (str); double num; bool i1, i2, s1, s2; @@ -305,6 +351,7 @@ %!assert (str2double (["2 + j";"1.25e-3";"-05"]), [2+i; 1.25e-3; -5]) %!assert (str2double ({"2 + j","1.25e-3","-05"}), [2+i, 1.25e-3, -5]) %!assert (str2double (1), NaN) +%!assert (str2double ("1 2 3 4"), NaN) %!assert (str2double ("Hello World"), NaN) %!assert (str2double ("NaN"), NaN) %!assert (str2double ("NA"), NA)