Mercurial > hg > octave-lyh
changeset 14077:b6eeeb67fa3f stable
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.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 20 Dec 2011 18:06:07 -0500 |
parents | 9aff66860e03 |
children | 941d19370065 |
files | src/DLD-FUNCTIONS/str2double.cc |
diffstat | 1 files changed, 54 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/str2double.cc +++ b/src/DLD-FUNCTIONS/str2double.cc @@ -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)