1 function [num,status,strarray] =
str2double(s,cdelim,rdelim,ddelim)
2 %% STR2DOUBLE converts strings into numeric values
3 %% [NUM, STATUS,STRARRAY] = STR2DOUBLE(STR)
5 %% STR2DOUBLE can replace STR2NUM, but avoids the insecure use of EVAL
6 %% on unknown data [1].
8 %% STR can be the form
'[+-]d[.]dd[[eE][+-]ddd]'
9 %% d can be any of digit from 0 to 9, [] indicate optional elements
10 %% NUM is the corresponding numeric value.
11 %%
if the conversion fails, status is -1 and NUM is NaN.
12 %% STATUS = 0: conversion was successful
13 %% STATUS = -1: couldnot convert
string into numeric value
14 %% STRARRAY is a cell array of strings.
16 %% Elements which are not defined or not valid
return NaN and
17 %% the STATUS becomes -1
18 %% STR can be also a character array or a cell array of strings.
19 %% Then, NUM and STATUS
return matrices of appropriate size.
21 %% STR can also contain multiple elements.
22 %%
default row-delimiters are:
23 %% NEWLINE, CARRIAGE RETURN and SEMICOLON i.e. ASCII 10, 13 and 59.
24 %%
default column-delimiters are:
25 %% TAB, SPACE and COMMA i.e. ASCII 9, 32, and 44.
26 %%
default decimal delimiter is
'.' char(46), sometimes (e.g in
27 %% Tab-delimited text files generated by Excel export in Europe)
28 %% might used
',' as decimal delimiter.
30 %% [NUM, STATUS] = STR2DOUBLE(STR,CDELIM,RDELIM,DDELIM)
31 %% CDELIM .. [OPTIONAL] user-specified column delimiter
32 %% RDELIM .. [OPTIONAL] user-specified row delimiter
33 %% DDELIM .. [OPTIONAL] user-specified decimal delimiter
34 %% CDELIM, RDELIM and DDELIM must contain only
35 %% NULL, NEWLINE, CARRIAGE RETURN, SEMICOLON, COLON, SLASH, TAB, SPACE, COMMA, or ()[]{}
36 %% i.e. ASCII 0,9,10,11,12,13,14,32,33,34,40,41,44,47,58,59,91,93,123,124,125
44 %% 3.1400 4.4440 0.7000
47 %% line =
'200,300,400,NaN,-inf,cd,yes,no,999,maybe,NaN';
50 %% 200 300 400 NaN -Inf NaN NaN NaN 999 NaN NaN
52 %% 0 0 0 0 0 -1 -1 -1 0 -1 0
55 %% [1] David A. Wheeler, Secure Programming for Linux and Unix HOWTO.
58 %% This program is free software; you can redistribute it and/or
59 %% modify it under the terms of the GNU General Public License
60 %% as published by the Free Software Foundation; either version 2
61 %% of the License, or (at your option) any later version.
63 %% This program is distributed in the hope that it will be useful,
64 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
65 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66 %% GNU General Public License
for more details.
68 %% You should have received a copy of the GNU General Public License
69 %% along with
this program;
if not, write to the Free Software
70 %% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
73 %% $Id:
str2double.m 2602 2011-02-03 13:05:03Z schloegl $
74 %% Copyright (C) 2004,2008 by Alois Schloegl <a.schloegl@ieee.org>
75 %% This
function is part of Octave-Forge http:
77 FLAG_OCTAVE = exist(
'OCTAVE_VERSION',
'builtin');
80 % valid_char =
'0123456789eE+-.nNaAiIfF'; % digits, sign, exponent,NaN,Inf
81 valid_delim = char(sort([0,9:14,32:34,abs(
'()[]{},;:"|/')])); % valid delimiter
83 error(
'missing input argument.')
86 cdelim =
char([9,32,abs(',')]); % column delimiter
89 cdelim =
char(sort(cdelim(:)));
90 tmp = [1;1+find(diff(abs(cdelim))>0)];
91 cdelim = cdelim(tmp)';
94 rdelim =
char([0,10,13,abs(';')]); % row delimiter
97 rdelim =
char(sort(rdelim(:)));
98 tmp = [1;1+find(diff(abs(rdelim))>0)];
99 rdelim = rdelim(tmp)';
103 elseif length(ddelim)~=1,
104 error('decimal delimiter must be exactly one character.');
107 % check if RDELIM and CDELIM are distinct
108 delim = sort(abs([cdelim,rdelim,ddelim]));
109 tmp = [1; 1 + find(diff(delim')>0)]';
111 %[length(delim),length(cdelim),length(rdelim)]
112 if length(delim) < (length(cdelim)+length(rdelim))+1, % length(ddelim) must be one.
113 error('row, column and decimal delimiter are not distinct.');
116 % check if delimiters are valid
117 tmp = sort(abs([cdelim,rdelim]));
118 flag = zeros(size(tmp));
121 while (k1 <= length(tmp)) && (k2 <= length(valid_delim)),
122 if tmp(k1) == valid_delim(k2),
125 elseif tmp(k1) < valid_delim(k2),
127 elseif tmp(k1) > valid_delim(k2),
132 error('Invalid delimiters!');
135 %%%%% various input parameters
137 if all(s<256) && all(s>=0)
140 error('STR2DOUBLE: input variable must be a
string')
154 if all(size(s)>1), %%
char array transformed into a
string.
156 tmp = find(~isspace(s(k,:)));
157 strarray{k,1} = s(k,min(tmp):max(tmp));
165 s(end+1) = rdelim(1); % add stop sign; makes sure last digit is not skipped
168 for k = 1:length(rdelim),
169 RD = RD | (s==rdelim(k));
172 for k = 1:length(cdelim),
173 CD = CD | (s==cdelim(k));
176 k1 = 1; % current row
177 k2 = 0; % current column
178 k3 = 0; % current element
182 %
while (ix < sl) & any(abs(s(ix))==[rdelim,cdelim]),
183 while (ix < sl) && CD(ix),
191 %
if any(abs(s(ix))==[cdelim(1),rdelim(1)]),
199 strarray{k1,k2} = [];
201 strarray{k1,k2} = s(ta:te);
203 %strarray{k1,k2} = [ta,te];
206 %
while any(abs(s(ix))==[cdelim(1),rdelim(1)]) & (ix < sl),
207 while CD(ix) && (ix < sl),
208 flag = flag | RD(ix);
223 error(
'STR2DOUBLE: invalid input argument');
226 [nr,nc]= size(strarray);
227 status = zeros(nr,nc);
228 num = repmat(NaN,nr,nc);
234 status(k1,k2) = -1; %%
return error code
242 l = min(2,length(t));
244 l = min(2,length(t));
249 if strcmp(lower(t(l:end)),
'inf')
252 elseif strcmp(lower(t(l:end)),'nan');
259 if FLAG_OCTAVE, %% Octave
260 [v,tmp2,c] = sscanf(
char(t),'%f %s','C');
261 elseif all(VER(1:2)=='3.') && any(VER(3)=='567'); %% FreeMat 3.5, 3.6, 3.7
262 [v,c,em] = sscanf(
char(t),'%f %s');
265 [v,c,em,ni] = sscanf(
char(t),'%f %s');
266 c = c * (ni>length(t));