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

20 ビュー (過去 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
Bryan Conklin
Bryan Conklin 2020 年 2 月 3 日
Thanks Cam! strncmp was the most appropriate function for me here.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeArgument Definitions についてさらに検索

製品


リリース

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by