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