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

16 visualizzazioni (ultimi 30 giorni)
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.

Risposta accettata

Cam Salzberger
Cam Salzberger il 29 Gen 2020
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 Commenti
Cam Salzberger
Cam Salzberger il 30 Gen 2020
Modificato: Cam Salzberger il 30 Gen 2020
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

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Argument Definitions in Help Center e File Exchange

Prodotti


Release

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by