How do I use the inputParser to validate my required input is a string from a defined set of acceptable strings?

18 次查看(过去 30 天)
I am having trouble with my function parsing a required string input. I want it to validate the input is an acceptable string. Code with subsequent error as a comment:
p = inputParser;
argName = 'monkey';
monkeys = [ "toejam","earl" ];
validationFcn = @(x) any(validatestring(x,monkeys));
addRequired(p,argName,validationFcn);
parse(p,"toejam")
% The value of 'monkey' is invalid. Invalid data type. First argument must be numeric or logical.
Why is it looking for a numeric input when I have the validation function defined using strings?
Thank you in advance for any help.

采纳的回答

Cam Salzberger
Cam Salzberger 2020-1-29
Hello Bryan,
validatestring doesn't return a logical matrix of validated values, it returns the full string that is matched. When you then feed it into any it errors because any is looking for a numeric or logical input. Since the validation function fails, the inputParser assumes the input is invalid.
Since validatestring returns an argument if it's correct, but the validation function in inputParser is just looking for an exception or not, I've found it simplest to just define a local or nested function to do the string validation without a return. Something like this:
p = inputParser;
argName = 'monkey';
monkeys = [ "toejam","earl" ];
validationFcn = @(x) validateStringParameter(x,monkeys,mfilename,argName);
addRequired(p,argName,validationFcn);
parse(p,"toejam")
function validateStringParameter(varargin)
validatestring(varargin{:});
end
-Cam
  3 个评论
Cam Salzberger
Cam Salzberger 2020-1-30
编辑:Cam Salzberger 2020-1-30
The mfilename and subsequent argument name is just to give a more clear error message if the validatestring fails. Up to you what kind of error message you want to see.
validatestring is designed to match partial input, and return the full name of the matched string. If you're okay with that, but then subsequently need that full string to set a property or something, you have a couple options:
  • Since this argument seems to be a required, ordinal (based on position) argument, you can simply not add that to the list of inputs to be used with inputParser, and validate it separately. Something like:
function myFunc(in1, varargin)
in1Full = validatestring(in1, ["OneValue" "AnotherValue"]);
parser = inputParser;
% ... add other arguments ...
parse(parser, varargin{:})
% ...
end
  • Another option would be to leave the argument being parsed by the inputParser, then do another validateString later on, not really for the validation, simply to get the full string value.
  • Similar to above, with more complexity and less inefficiency, would be to get the full value using strncmpi (to handle partial matches and ignoring case). Something like:
possibleValues = ["OneValue" "AnotherValue"];
myInput = "one";
whichValue = strncmpi(myInput, possibleValues, strlength(myInput))
myFullInput = possibleValues(whichValue);
If you don't want partial matching, and would rather require that the user input the string exactly as expected, then don't use validatestring. Instead, go with something more like @(inVal)any(strcmp(inVal,possVal)) as your validation function.
I believe that all of the code here works with string or char input and allowable values, or a mix thereof.
-Cam

请先登录,再进行评论。

更多回答(0 个)

类别

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

产品


版本

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by