Mercurial > hg > octave-lyh
annotate scripts/strings/str2double.m @ 8920:eb63fbe60fab
update copyright notices
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 07 Mar 2009 10:41:27 -0500 |
parents | cadc73247d65 |
children |
rev | line source |
---|---|
8920 | 1 ## Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by Alois Schloegl |
5185 | 2 ## |
3 ## This file is part of Octave. | |
4 ## | |
5 ## Octave is free software; you can redistribute it and/or modify it | |
6 ## under the terms of the GNU General Public License as published by | |
7016 | 7 ## the Free Software Foundation; either version 3 of the License, or (at |
8 ## your option) any later version. | |
5185 | 9 ## |
10 ## Octave is distributed in the hope that it will be useful, but | |
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 ## General Public License for more details. | |
14 ## | |
15 ## You should have received a copy of the GNU General Public License | |
7016 | 16 ## along with Octave; see the file COPYING. If not, see |
17 ## <http://www.gnu.org/licenses/>. | |
5185 | 18 |
5187 | 19 ## -*- texinfo -*- |
20 ## @deftypefn {Function File} {[@var{num}, @var{status}, @var{strarray}] =} str2double (@var{str}, @var{cdelim}, @var{rdelim}, @var{ddelim}) | |
21 ## Convert strings into numeric values. | |
5184 | 22 ## |
5187 | 23 ## @code{str2double} can replace @code{str2num}, but avoids the use of |
24 ## @code{eval} on unknown data. | |
5184 | 25 ## |
5187 | 26 ## @var{str} can be the form @samp{[+-]d[.]dd[[eE][+-]ddd]} in which |
27 ## @samp{d} can be any of digit from 0 to 9, and @samp{[]} indicate | |
28 ## optional elements. | |
29 ## | |
30 ## @var{num} is the corresponding numeric value. If the conversion | |
31 ## fails, status is -1 and @var{num} is NaN. | |
5184 | 32 ## |
5187 | 33 ## @var{status} is 0 if the conversion was successful and -1 otherwise. |
34 ## | |
35 ## @var{strarray} is a cell array of strings. | |
36 ## | |
37 ## Elements which are not defined or not valid return NaN and the | |
38 ## @var{status} becomes -1. | |
5184 | 39 ## |
5187 | 40 ## If @var{str} is a character array or a cell array of strings, then |
41 ## @var{num} and @var{status} return matrices of appropriate size. | |
42 ## | |
43 ## @var{str} can also contain multiple elements separated by row and | |
44 ## column delimiters (@var{cdelim} and @var{rdelim}). | |
45 ## | |
46 ## The parameters @var{cdelim}, @var{rdelim}, and @var{ddelim} are | |
47 ## optional column, row, and decimal delimiters. | |
5184 | 48 ## |
5187 | 49 ## The default row-delimiters are newline, carriage return and semicolon |
50 ## (ASCII 10, 13 and 59). The default column-delimiters are tab, space | |
51 ## and comma (ASCII 9, 32, and 44). The default decimal delimiter is | |
52 ## @samp{.} (ASCII 46). | |
5184 | 53 ## |
5187 | 54 ## @var{cdelim}, @var{rdelim}, and @var{ddelim} must contain only nul, |
55 ## newline, carriage return, semicolon, colon, slash, tab, space, comma, | |
56 ## or @samp{()[]@{@}} (ASCII 0, 9, 10, 11, 12, 13, 14, 32, 33, 34, 40, | |
57 ## 41, 44, 47, 58, 59, 91, 93, 123, 124, 125). | |
58 ## | |
59 ## Examples: | |
60 ## | |
61 ## @example | |
8442
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
62 ## @group |
5187 | 63 ## str2double ("-.1e-5") |
64 ## @result{} -1.0000e-006 | |
5184 | 65 ## |
5187 | 66 ## str2double (".314e1, 44.44e-1, .7; -1e+1") |
67 ## @result{} | |
68 ## 3.1400 4.4440 0.7000 | |
69 ## -10.0000 NaN NaN | |
5184 | 70 ## |
7031 | 71 ## line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN"; |
5187 | 72 ## [x, status] = str2double (line) |
7031 | 73 ## @result{} x = |
74 ## 200 300 NaN -Inf NaN NaN 999 NaN NaN | |
75 ## @result{} status = | |
76 ## 0 0 0 0 -1 -1 0 -1 0 | |
8442
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
77 ## @end group |
5187 | 78 ## @end example |
8442
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
79 ## @seealso{str2num} |
5187 | 80 ## @end deftypefn |
81 | |
82 ## Author: Alois Schloegl <a.schloegl@ieee.org> | |
83 ## Adapted-by: jwe | |
5183 | 84 |
5185 | 85 function [num, status, strarray] = str2double (s, cdelim, rdelim, ddelim) |
86 | |
87 ## digits, sign, exponent,NaN,Inf | |
88 ## valid_char = '0123456789eE+-.nNaAiIfF'; | |
5183 | 89 |
8506 | 90 ## Valid delimiters. |
5185 | 91 valid_delim = char (sort ([0, 9:14, 32:34, abs("()[]{},;:\"|/")])); |
5184 | 92 |
8442
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
93 if (nargin < 1 || nargin > 4) |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
94 print_usage (); |
5185 | 95 endif |
5184 | 96 |
5185 | 97 if (nargin < 2) |
8506 | 98 ## Column delimiter. |
5185 | 99 cdelim = char ([9, 32, abs(",")]); |
100 else | |
8506 | 101 ## Make unique cdelim. |
5185 | 102 cdelim = char (sort (cdelim(:))); |
103 tmp = [1; 1+find(diff(abs(cdelim))>0)]; | |
104 cdelim = cdelim(tmp)'; | |
105 endif | |
106 | |
107 if (nargin < 3) | |
8506 | 108 ## Row delimiter. |
5185 | 109 rdelim = char ([0, 10, 13, abs(";")]); |
110 else | |
8506 | 111 ## Make unique rdelim. |
5185 | 112 rdelim = char (sort (rdelim(:))); |
113 tmp = [1; 1+find(diff(abs(rdelim))>0)]; | |
114 rdelim = rdelim(tmp)'; | |
115 endif | |
116 | |
117 if (nargin < 4) | |
7428 | 118 ddelim = "."; |
5185 | 119 elseif (length (ddelim) != 1) |
120 error ("decimal delimiter must be exactly one character"); | |
121 endif | |
5183 | 122 |
8506 | 123 ## Check if RDELIM and CDELIM are distinct. |
5184 | 124 |
5185 | 125 delim = sort (abs ([cdelim, rdelim, ddelim])); |
126 tmp = [1, 1+find(diff(delim)>0)]; | |
127 delim = delim(tmp); | |
128 ## [length(delim),length(cdelim),length(rdelim)] | |
129 if (length (delim) < (length(cdelim) + length(rdelim))+1) | |
130 ## length (ddelim) must be one. | |
131 error ("row, column and decimal delimiter are not distinct"); | |
132 endif | |
5184 | 133 |
8506 | 134 ## Check if delimiters are valid. |
5185 | 135 tmp = sort (abs ([cdelim, rdelim])); |
136 flag = zeros (size (tmp)); | |
8506 | 137 curr_row = 1; |
138 curr_col = 1; | |
139 while (curr_row <= length (tmp) && curr_col <= length (valid_delim)), | |
140 if (tmp(curr_row) == valid_delim(curr_col)) | |
141 flag(curr_row) = 1; | |
142 curr_row++; | |
143 elseif (tmp(curr_row) < valid_delim(curr_col)) | |
144 curr_row++; | |
145 elseif (tmp(curr_row) > valid_delim(curr_col)) | |
146 curr_col++; | |
5185 | 147 endif |
148 endwhile | |
149 if (! all (flag)) | |
150 error ("invalid delimiters!"); | |
151 endif | |
5183 | 152 |
8506 | 153 ## Various input parameters. |
5183 | 154 |
5185 | 155 if (isnumeric (s)) |
156 if (all (s < 256) && all (s >= 0)) | |
157 s = char (s); | |
158 else | |
159 error ("str2double: input variable must be a string"); | |
160 endif | |
161 endif | |
5183 | 162 |
5185 | 163 if (isempty (s)) |
164 num = []; | |
165 status = 0; | |
166 return; | |
167 elseif (iscell (s)) | |
168 strarray = s; | |
169 elseif (ischar (s) && all (size (s) > 1)) | |
8506 | 170 ## Char array transformed into a string. |
5185 | 171 for k = 1:size (s, 1) |
172 tmp = find (! isspace (s(k,:))); | |
173 strarray{k,1} = s(k,min(tmp):max(tmp)); | |
174 endfor | |
175 elseif (ischar (s)), | |
176 num = []; | |
177 status = 0; | |
178 strarray = {}; | |
8506 | 179 ## Add stop sign; makes sure last digit is not skipped. |
5185 | 180 s(end+1) = rdelim(1); |
181 RD = zeros (size (s)); | |
182 for k = 1:length (rdelim), | |
183 RD = RD | (s == rdelim(k)); | |
184 endfor | |
185 CD = RD; | |
186 for k = 1:length (cdelim), | |
8507 | 187 CD = CD | (s == cdelim(k)); |
5185 | 188 endfor |
5184 | 189 |
8506 | 190 curr_row = 1; |
191 curr_col = 0; | |
192 curr_elt = 0; | |
5183 | 193 |
5185 | 194 sl = length (s); |
195 ix = 1; | |
196 ## while (ix < sl) & any(abs(s(ix))==[rdelim,cdelim]), | |
197 while (ix < sl && CD(ix)) | |
5920 | 198 ix++; |
5185 | 199 endwhile |
200 ta = ix; | |
201 te = []; | |
202 while (ix <= sl) | |
203 if (ix == sl) | |
204 te = sl; | |
205 endif | |
206 ## if any(abs(s(ix))==[cdelim(1),rdelim(1)]), | |
207 if (CD(ix)) | |
208 te = ix - 1; | |
209 endif | |
210 if (! isempty (te)) | |
8506 | 211 curr_col++; |
212 curr_elt++; | |
213 strarray{curr_row,curr_col} = s(ta:te); | |
214 ## strarray{curr_row,curr_col} = [ta,te]; | |
5185 | 215 |
216 flag = 0; | |
217 ## while any(abs(s(ix))==[cdelim(1),rdelim(1)]) & (ix < sl), | |
218 while (CD(ix) && ix < sl) | |
219 flag = flag | RD(ix); | |
220 ix++; | |
221 endwhile | |
5183 | 222 |
5185 | 223 if (flag) |
8506 | 224 curr_col = 0; |
225 curr_row++; | |
5185 | 226 endif |
227 ta = ix; | |
228 te = []; | |
229 endif | |
230 ix++; | |
231 endwhile | |
232 else | |
233 error ("str2double: invalid input argument"); | |
234 endif | |
5184 | 235 |
5185 | 236 [nr, nc]= size (strarray); |
237 status = zeros (nr, nc); | |
238 num = repmat (NaN, nr, nc); | |
5184 | 239 |
8506 | 240 for curr_row = 1:nr |
241 for curr_col = 1:nc | |
242 t = strarray{curr_row,curr_col}; | |
5185 | 243 if (length (t) == 0) |
8506 | 244 ## Return error code. |
245 status(curr_row,curr_col) = -1; | |
246 num(curr_row,curr_col) = NaN; | |
5185 | 247 else |
8506 | 248 ## Get mantisse. |
5185 | 249 g = 0; |
250 v = 1; | |
251 if (t(1) == "-") | |
252 v = -1; | |
253 l = min (2, length(t)); | |
254 elseif (t(1) == "+") | |
255 l = min (2, length (t)); | |
256 else | |
257 l = 1; | |
258 endif | |
5184 | 259 |
5185 | 260 if (strcmpi (t(l:end), "inf")) |
8506 | 261 num(curr_row,curr_col) = v*Inf; |
5185 | 262 elseif (strcmpi (t(l:end), "NaN")); |
8506 | 263 num(curr_row,curr_col) = NaN; |
5185 | 264 else |
265 if (ddelim == ".") | |
8507 | 266 t(t == ddelim) = "."; |
5185 | 267 endif |
5187 | 268 [v, tmp2, c] = sscanf(char(t), "%f %s", "C"); |
5185 | 269 ## [v,c,em,ni] = sscanf(char(t),"%f %s"); |
270 ## c = c * (ni>length(t)); | |
271 if (c == 1), | |
8506 | 272 num(curr_row,curr_col) = v; |
5185 | 273 else |
8506 | 274 num(curr_row,curr_col) = NaN; |
275 status(curr_row,curr_col) = -1; | |
5185 | 276 endif |
277 endif | |
278 endif | |
279 endfor | |
280 endfor | |
5184 | 281 |
5185 | 282 endfunction |
8442
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
283 |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
284 %!error <Invalid call to str2double> str2double(); |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
285 %!error <Invalid call to str2double> str2double("1e10", " ", "\n", ".", "x"); |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
286 %!assert (str2double ("-.1e-5"), -1.0000e-006); |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
287 %!assert (str2double (".314e1, 44.44e-1, .7; -1e+1"), |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
288 %! [3.1400, 4.4440, 0.7000; -10.0000, NaN, NaN]); |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
289 %!test |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
290 %! line = "200, 300, NaN, -inf, yes, no, 999, maybe, NaN"; |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
291 %! [x, status] = str2double (line); |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
292 %! assert (x, [200, 300, NaN, -Inf, NaN, NaN, 999, NaN, NaN]); |
502e58a0d44f
Fix docstrings, add examples, references and tests to string functions
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7428
diff
changeset
|
293 %! assert (status, [0, 0, 0, 0, -1, -1, 0, -1, 0]); |