TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
str2double.m
Go to the documentation of this file.
1 function [num,status,strarray] = str2double(s,cdelim,rdelim,ddelim)
2 %% STR2DOUBLE converts strings into numeric values
3 %% [NUM, STATUS,STRARRAY] = STR2DOUBLE(STR)
4 %%
5 %% STR2DOUBLE can replace STR2NUM, but avoids the insecure use of EVAL
6 %% on unknown data [1].
7 %%
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.
15 %%
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.
20 %%
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.
29 %%
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
37 %%
38 %% Examples:
39 %% str2double('-.1e-5')
40 %% ans = -1.0000e-006
41 %%
42 %% str2double('.314e1, 44.44e-1, .7; -1e+1')
43 %% ans =
44 %% 3.1400 4.4440 0.7000
45 %% -10.0000 NaN NaN
46 %%
47 %% line ='200,300,400,NaN,-inf,cd,yes,no,999,maybe,NaN';
48 %% [x,status]=str2double(line)
49 %% x =
50 %% 200 300 400 NaN -Inf NaN NaN NaN 999 NaN NaN
51 %% status =
52 %% 0 0 0 0 0 -1 -1 -1 0 -1 0
53 %%
54 %% Reference(s):
55 %% [1] David A. Wheeler, Secure Programming for Linux and Unix HOWTO.
56 %% http://en.tldp.org/HOWTO/Secure-Programs-HOWTO/
57 
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.
62 %%
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.
67 %%
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.
71 
72 %% $Revision: 1.4 $
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://octave.sourceforge.net/
76 
77 FLAG_OCTAVE = exist('OCTAVE_VERSION','builtin');
78 VER = version;
79 
80 % valid_char = '0123456789eE+-.nNaAiIfF'; % digits, sign, exponent,NaN,Inf
81 valid_delim = char(sort([0,9:14,32:34,abs('()[]{},;:"|/')])); % valid delimiter
82 if nargin < 1,
83  error('missing input argument.')
84 end;
85 if nargin < 2,
86  cdelim = char([9,32,abs(',')]); % column delimiter
87 else
88  % make unique cdelim
89  cdelim = char(sort(cdelim(:)));
90  tmp = [1;1+find(diff(abs(cdelim))>0)];
91  cdelim = cdelim(tmp)';
92 end;
93 if nargin < 3,
94  rdelim = char([0,10,13,abs(';')]); % row delimiter
95 else
96  % make unique rdelim
97  rdelim = char(sort(rdelim(:)));
98  tmp = [1;1+find(diff(abs(rdelim))>0)];
99  rdelim = rdelim(tmp)';
100 end;
101 if nargin<4,
102  ddelim = '.';
103 elseif length(ddelim)~=1,
104  error('decimal delimiter must be exactly one character.');
105 end;
106 
107 % check if RDELIM and CDELIM are distinct
108 delim = sort(abs([cdelim,rdelim,ddelim]));
109 tmp = [1; 1 + find(diff(delim')>0)]';
110 delim = delim(tmp);
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.');
114 end;
115 
116 % check if delimiters are valid
117 tmp = sort(abs([cdelim,rdelim]));
118 flag = zeros(size(tmp));
119 k1 = 1;
120 k2 = 1;
121 while (k1 <= length(tmp)) && (k2 <= length(valid_delim)),
122  if tmp(k1) == valid_delim(k2),
123  flag(k1) = 1;
124  k1 = k1 + 1;
125  elseif tmp(k1) < valid_delim(k2),
126  k1 = k1 + 1;
127  elseif tmp(k1) > valid_delim(k2),
128  k2 = k2 + 1;
129  end;
130 end;
131 if ~all(flag),
132  error('Invalid delimiters!');
133 end;
134 
135 %%%%% various input parameters
136 if isnumeric(s)
137  if all(s<256) && all(s>=0)
138  s = char(s);
139  else
140  error('STR2DOUBLE: input variable must be a string')
141  end;
142 end;
143 
144 num = [];
145 status = 0;
146 strarray = {};
147 if isempty(s),
148  return;
149 
150 elseif iscell(s),
151  strarray = s;
152 
153 elseif ischar(s)
154 if all(size(s)>1), %% char array transformed into a string.
155  for k = 1:size(s,1),
156  tmp = find(~isspace(s(k,:)));
157  strarray{k,1} = s(k,min(tmp):max(tmp));
158  end;
159 
160 else %if isschar(s),
161  num = [];
162  status = 0;
163  strarray = {};
164 
165  s(end+1) = rdelim(1); % add stop sign; makes sure last digit is not skipped
166 
167  RD = zeros(size(s));
168  for k = 1:length(rdelim),
169  RD = RD | (s==rdelim(k));
170  end;
171  CD = RD;
172  for k = 1:length(cdelim),
173  CD = CD | (s==cdelim(k));
174  end;
175 
176  k1 = 1; % current row
177  k2 = 0; % current column
178  k3 = 0; % current element
179 
180  sl = length(s);
181  ix = 1;
182  %while (ix < sl) & any(abs(s(ix))==[rdelim,cdelim]),
183  while (ix < sl) && CD(ix),
184  ix = ix + 1;
185  end;
186  ta = ix; te = [];
187  while ix <= sl;
188  if (ix == sl),
189  te = sl;
190  end;
191  %if any(abs(s(ix))==[cdelim(1),rdelim(1)]),
192  if CD(ix),
193  te = ix - 1;
194  end;
195  if ~isempty(te),
196  k2 = k2 + 1;
197  k3 = k3 + 1;
198  if te<ta,
199  strarray{k1,k2} = [];
200  else
201  strarray{k1,k2} = s(ta:te);
202  end;
203  %strarray{k1,k2} = [ta,te];
204 
205  flag = 0;
206  %while any(abs(s(ix))==[cdelim(1),rdelim(1)]) & (ix < sl),
207  while CD(ix) && (ix < sl),
208  flag = flag | RD(ix);
209  ix = ix + 1;
210  end;
211 
212  if flag,
213  k2 = 0;
214  k1 = k1 + 1;
215  end;
216  ta = ix;
217  te = [];
218  end;
219  ix = ix + 1;
220  end;
221 end;
222 else
223  error('STR2DOUBLE: invalid input argument');
224 end;
225 
226 [nr,nc]= size(strarray);
227 status = zeros(nr,nc);
228 num = repmat(NaN,nr,nc);
229 
230 for k1 = 1:nr,
231 for k2 = 1:nc,
232  t = strarray{k1,k2};
233  if (length(t)==0),
234  status(k1,k2) = -1; %% return error code
235  num(k1,k2) = NaN;
236  else
237  %% get mantisse
238  g = 0;
239  v = 1;
240  if t(1)=='-',
241  v = -1;
242  l = min(2,length(t));
243  elseif t(1)=='+',
244  l = min(2,length(t));
245  else
246  l = 1;
247  end;
248 
249  if strcmp(lower(t(l:end)),'inf')
250  num(k1,k2) = v*inf;
251 
252  elseif strcmp(lower(t(l:end)),'nan');
253  num(k1,k2) = NaN;
254 
255  else
256  if ddelim=='.',
257  t(t==ddelim)='.';
258  end;
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');
263  c = 1;
264  else %% Matlab
265  [v,c,em,ni] = sscanf(char(t),'%f %s');
266  c = c * (ni>length(t));
267  end;
268  if (c==1),
269  num(k1,k2) = v;
270  else
271  num(k1,k2) = NaN;
272  status(k1,k2) = -1;
273  end
274  end
275  end;
276 end;
277 end;
278 
str2double
function str2double(in s, in cdelim, in rdelim, in ddelim)