Error when using validatestring in inputParser addOptional

9 次查看(过去 30 天)
I'm getting the following error when running isenExpan('a','m',2,1.4,'sub') with the code below:
??? Error using ==> isenExpan
Argument 'sonic' failed validation
@(x)validatestring(x,validSonic).
code:
function out = isenExpan(from,to,val,gam,varargin)
%%error checking
validTypes = {'m', 'a', 'p', 't', 'd'};
validSonic = {'super', 'sub'};
p = inputParser;
p.FunctionName = 'isenExpan';
p.addRequired('from', @(x)validatestring(x,validTypes));
p.addRequired('to', @(x)validatestring(x,validTypes));
p.addRequired('val', @isnumeric);
p.addRequired('gam', @(x)validateattributes(x,{'numeric'},{'>',1,'<',1.5}));
p.addOptional('sonic', 'super', @(x)validatestring(x,validSonic));
p.parse(from,to,val,gam,varargin{:});
I'm giving sonic a valid input, and when I step through itin debug mode, validatestring returns 'sub' and not false.
Has anyone else seen or heard of this problem?
  1 个评论
David Ternet
David Ternet 2013-8-12
Another question related to this. Is anyone else frustrated by the way many of these APIs rely on exceptions or text display results? For example, why couldn't validatestring (or inputparser.parse) return a simple true/false instead of using an exception to indicate failure? It seems a bit costly to add try/catch blocks around many of these API calls just to find out if something was successful or not.

请先登录,再进行评论。

采纳的回答

Sven
Sven 2012-2-3
Hi Kevin,
The problem lies in validatestring... from the docs: "the validatestring function returns the matching string in validstr". So it returns the matching string, rather than TRUE, FALSE, or nothing (as required by inputParser).
Try changing that line to:
p.addOptional('sonic', 'super', @(x)any(strcmp(x,validSonic)));
EDIT:
Actually, I can see why we would expect it to work... it seems that inputParser.parse has no trouble when validatestring returns the string (rather than an error) to a required argument, but it seems not to like the same validation of an optional argument... weird...
The proposed solution still works just as well, but I'm a little perplexed about why the problem occurred in the first place. Unfortunately inputParser.parse() is an internal MATLAB function, so there's no chance to follow the code inside and see why it goes wrong.
  3 个评论
Kevin Holst
Kevin Holst 2012-2-3
I've dug a little deeper and found that the reason it works on the required argument rather than the optional one is because the required one is a single character. If I make the optional argument a single character, it works fine. Weird.
Adam Danz
Adam Danz 2020-1-2
编辑:Adam Danz 2020-2-3
validatestring() returns a string scalar if validStrings is a string array or it returns a character vector if validStrings is a cell array of character vectors. Therefore, depending on which type of data you're using (string array or cell array of characters),
@(x)ischar(validatestring(x,validStrings))
@(x)isstring(validatestring(x,validStrings))
Note that in either case, 'x' can be a cell array or a string but the output will always match the class of validStrings (tested in r2019b).
An alternative validation would be
@(x)assert(ismember(x,validStrings),'Accepted inputs are\n%s',validStrings))
or for case insensitivity
@(x)assert(ismember(lower(x),lower(validStrings),'Accepted inputs are\n%s',validStrings))
or use any(strcmpi(x, validStrings))

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Argument Definitions 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by