Is there any other way to do the job without using eval?

Matlab experts say ' eval is evil'. I use eval in the case when I read Edit Text data in GUI and str2double is not applicable. For example, I need to type, read and save (in cell-array) an arbitrary array with arbitrary length, say A=[1,5,9]. I do:
set(handles.A_edit,'String','[1,5,9]')
C{1}=get(handles.A_edit,'String');
A=eval(C{1});
Is there any other way to do the job without using eval?

1 commentaire

G A
G A le 30 Déc 2012
Modifié(e) : G A le 30 Déc 2012
By the way, what about subs?
>> a='[1,2,3]';
>> subs(a)
ans =
1 2 3

Connectez-vous pour commenter.

 Réponse acceptée

Azzi Abdelmalek
Azzi Abdelmalek le 30 Déc 2012
Modifié(e) : Azzi Abdelmalek le 30 Déc 2012
A=str2double(get(handles.A_edit,'String'))

9 commentaires

a='[1,2,3]'
a =
[1,2,3]
>> str2double(a)
ans =
NaN
thanks, it does work
>> a='[1,2,3]'
a =
[1,2,3]
>> str2num(a)
ans =
1 2 3
Jan
Jan le 30 Déc 2012
Modifié(e) : Jan le 30 Déc 2012
@G A: str2num is based on an eval also, such that it does not match the match the restrictions of the question.
G A
G A le 30 Déc 2012
And, I suspect, subs as well?
G A
G A le 30 Déc 2012
Jan, which way then is better to use: str2num, which is, as you say, based on eval or directly eval?
>> a='1:100000000'
a =
1:100000000
>> tic;b=eval(a);toc
Elapsed time is 0.307041 seconds.
>> tic;c=str2num(a);toc
Elapsed time is 0.313607 seconds.
So eval is slightly faster.
Jan
Jan le 30 Déc 2012
Modifié(e) : Jan le 30 Déc 2012
@G A: subs concerns symbolical calculations and here eval is a completely different story: neither evil nor prone to errors, but the best method to evaluate a symbolical expression numerically.
I recommend neither str2num nor the direct usage of eval. Try this:
str2num('system(''cmd'')')
If you are stuck in the command shell interaction inside Matlab's command window, type "exit" to stop the nonsense. Equivalent system calls are used frequently to crack web-based services using a standard input masks. Although you think you can trust the users of your Matlab GUI, it is a good programming practice to avoid a string evaluation ever, under all circumstances and in general and at all.
When I need to input a vector in a GUI, I implement three edit fields like (sorry for the poor graphics):
[edit1] : [edit2] : [edit3]
Then I check if the users has inserted values for all three fields and create the vector by:
v1 = sscanf(get(edit1_H, 'String'), '%g', 1);
v2 = sscanf(get(edit2_H, 'String'), '%g', 1);
v3 = sscanf(get(edit3_H, 'String'), '%g', 1);
... checks with ISNAN ...
v = colon(v1, v2, v3);
Of course eval and str2num would handle '[1:10, 11, 13:17, 27]' also, but also 'sum = 23' and this assigns a value to a symbol, which is a built-in function and in debug mode this will lead to extremely surprising effects. If the user types 'o' instead of '0' by accident, the results may be strange also, when 'o' is a variable already and the evil eval evaluates the string.
But, sigh, parsing inputs cannot be 100% secure. See e.g. EVAL bug and even sprintf allowed to obtain root privileges in older Matlab versions. So really evil users will break your program without eval also, but at least this happens less likely by mistakes and typos.
G A
G A le 30 Déc 2012
Thanks, Jan!
In some cases I also imput vectors using three fields as you have shown. However I did not think that so many hidden problems with str2num and eval exist.

Connectez-vous pour commenter.

Plus de réponses (1)

T1 = regexprep(get(handles.A_edit,'String'), '\[|\]', ' ');
T2 = regexp(T1, '[,;\s]', 'split');
Acell = str2double(T2);
A = cell2mat(Acell);

11 commentaires

T1 = regexprep('[1,2,3,4]', '\[|\]', ' ')
T1 =
1,2,3,4
>> T2 = regexp(T1, '[,;\s]', 'split')
T2 =
'' '1' '2' '3' '4' ''
>> Acell = str2double(T2)
Acell =
NaN 1 2 3 4 NaN
>> A = cell2mat(Acell)
Cell contents reference from a non-cell array object.
Revised:
T1 = regexprep(get(handles.A_edit,'String'), '\[|\]', '');
T2 = regexp(T1, '[,;\s]', 'split');
A = str2double(T2);
This would need more work if you expected the user to be able to enter two-dimensional arrays instead of vectors.
G A
G A le 31 Déc 2012
Modifié(e) : Walter Roberson le 31 Déc 2012
Thanks, !
How to deal with this kind of input:
'2:2:10'
or
'1:10'
instead of
'[2,4,6,8,10]' ?
if any(S == ':')
T2 = regexp(S, ':', 'split');
if length(T2) == 2 || (length(T2) == 3 & isempty(T2{2}))
T2(2:3) = {'1' T2{3}};
end
if length(T2) == 1
error('not enough roughage for colon')
elseif length(T2) == 3
A = str2double(T2{1}) : str2double(T2{2}) : str2double(T2{3});
else
error('too much roughage for colon')
end
else
%no colon to process
end
G A
G A le 31 Déc 2012
Thanks! I can now use your code as new function A=str2num1(S)
the code works allright with S='2:2:10' but with S='1:5' generates an error
Index exceeds matrix dimensions.
Error in teststr2num1>str2num1 (line 4)
T2(2:3) = {'1' T2{3}};
Hmmm. Okay.
if length(T2) == 2
T2(2:3) = {'1' T2{2}}
elseif length(T2) == 3 & any(cellfun(@isempty, T2))
error('Cannot colonize empty fields.')
end
Now it works OK. Thanks again, Walter! Whole function:
function A=str2num1(S)
if any(S == ':')
T2 = regexp(S, ':', 'split');
if length(T2) == 2
T2(2:3) = {'1' T2{2}};
elseif length(T2) == 3 && any(cellfun(@isempty, T2))
error('Cannot colonize empty fields.')
end
if length(T2) == 1
error('not enough roughage for colon')
elseif length(T2) == 3
A = str2double(T2{1}) : str2double(T2{2}) : str2double(T2{3});
else
error('too much roughage for colon')
end
else
%no colon to process
T1 = regexprep(S, '\[|\]', '');
T2 = regexp(T1, '[,;\s]', 'split');
A = str2double(T2);
end
one problem
g='[1 2 3 4]';%double spaces
G=str2num1(g)
G =
1 NaN 2 NaN 3 NaN 4
d='[1, 2, 3, 4]';%spaces
D=str2num1(d)
D =
1 NaN 2 NaN 3 NaN 4
T2 = regexp(T1, '[,;\s]+', 'split');
Note: with this modification, if the user enters (say) '[1,,,3]' then it would become [1 3] and the multiple delimiters would be ignored. If you want more error checking in the "no colon" section,
if regexp(S, '[\[,;\[]\s*[\[,;\[]')
error('multiple delimiters')
end
Mind you this will also reject '[[1],[2]]'. To do better, you need to define exactly which syntaxes you wish to permit.
G A
G A le 31 Déc 2012
Modifié(e) : G A le 31 Déc 2012
Thanks, Walter, and Happy New Year!

Connectez-vous pour commenter.

Catégories

Produits

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by