Can isstrprop search for 2 properties?

4 vues (au cours des 30 derniers jours)
Lachlan Downie
Lachlan Downie le 8 Avr 2019
Commenté : Rik le 9 Avr 2019
Im attempting to debug erroneous input to retreive a valid input from a user.
I want the input to be only a numeric value and am using isstrprop to test if the input is a digit,
however isstrprop(input, 'digit') returns false if the value has a decimal place. (as a period is not a digit)
Can I use isstrprop to search for digits and decimal places, or is there a better way of acheiving the same result?
Here is my code:
clear, clc;
NumInput = ('');
while isempty(NumInput)
NumInput = input('Hello!\nWelcome to my unit converter!\nPlease enter a numerical value to convert:\n\n', 's');
NumTest = isstrprop(NumInput, 'digit'); %Testing for digits
AlphaTest = isstrprop(NumInput, 'alpha'); %Testing for letters
AlphaNumTest = isstrprop(NumInput, 'AlphaNum'); %Testing for combination
if NumTest(1,:) == 1
NumInput = str2double(NumInput);
disp(NumInput);
elseif AlphaTest(1,:) == 1
fprintf('Please enter only a numeric value.\n\n');
NumInput = ('');
continue
elseif AlphaNumTest(1,:) == 1
NumTest = isstrprop(NumInput, 'digit');
NumsOnly = find(NumTest);
NumInput = str2double(NumInput(NumsOnly));
fprintf('\nOnly numerical values can be entered;\nUsing %1.5g\n\n', NumInput);
else
error('Please enter only a numerical value:');
NumInput = ('');
end
end
Surely these is a better way?
  2 commentaires
Guillaume
Guillaume le 8 Avr 2019
Modifié(e) : Guillaume le 8 Avr 2019
It can be done with a regular expression depending on what king of number input you allow/disallow. Are the following inputs allowed:
  • 1
  • 0.5
  • .5
  • 1e4
  • 1e+4
  • 1e-4
  • 1d4
  • 1d+4
  • 1d-4
  • +1
  • -1
  • -.5
  • .1e1
  • +inf
  • -inf
  • nan
All of these are valid number representations in matlab. Do you allow all of them.
Note that if you don't allow NaN, then the simplest may be to simply attempt to convert the input with str2double and if the result is NaN tell the user that what they entered is invalid.
Lachlan Downie
Lachlan Downie le 9 Avr 2019
Modifié(e) : Lachlan Downie le 9 Avr 2019
Ideally I just want to allow numbers negative, positive, and decimals (no letters).
e.g. 1.45 or -40
Which gave me the idea to use the zeros of an isstrprop to find everything in a string that isnt a letter:
NumInput = ('');
while isempty(NumInput)
NumInput = input('Hello!\nWelcome to my unit converter!\nPlease enter a numerical value to convert:\n\n', 's');
NumTest = isstrprop(NumInput, 'digit');
AlphaTest = isstrprop(NumInput, 'alpha');
AlphaNumTest = isstrprop(NumInput, 'AlphaNum');
if (NumTest(1,:) ~= 1) && (AlphaTest(1,:) == 0)
NumInput = str2double(NumInput);
disp(NumInput)
elseif (AlphaTest(1,:) ~= 1)
ZerosOnly = Zeros(AlphaTest);
NumInput = NumInput(ZerosOnly);
fprintf('Only Numerical Values can be entered.\nUsing %1.5g', NumInput);
end
end
But now I get the error:
'Operands to the || and && operators must be convertible to logical scalar values.
Error in Test (line 41)
if (NumTest(1,:) ~= 1) && (AlphaTest(1,:) == 0)'

Connectez-vous pour commenter.

Réponse acceptée

Guillaume
Guillaume le 9 Avr 2019
I would really recommend you use the approach of letting matlab do the conversion for you as I wrote in my comment and as Rik answered. It's really the most flexible and doesn't unnecessarily restrict the user from entering valid inputs.
If you're hell bent on only allowing numbers with no 'e' or 'd' notation, the following regular expression should work. It does more than just checking that the text just contain the allowed characters. It actually checks that the expression makes a valid number:
isvalid = ~isempty(regexp(strinput, '^[+-]?(\d*\.)?\d+$'))

Plus de réponses (1)

Rik
Rik le 9 Avr 2019
I would convert to double type and use ismember to check if all characters are allowed.
Alternatively you could just convert to double with str2double and test if the result is a NaN.
  2 commentaires
Guillaume
Guillaume le 9 Avr 2019
Modifié(e) : Guillaume le 9 Avr 2019
Yes, this is what I wrote in my comment, and really the simplest way to deal with the problem. This allows all valid number notations and leave matlab to do the validation for you.
I really see no point in forcing the user to write 100000000 instead of 1e9. With the latter, I'm sure I've got the correct number of 0s, with the former, not so sure...
So the code would be:
while true
strinput = input('Hello!\nWelcome to my unit converter!\nPlease enter a numerical value to convert:\n\n', 's');
NumInput = str2double(strinput);
if isfinite(NumInput) %catch failed conversion (NaN), the user entering NaN or +/- Inf
break;
else
fprintf('\nPlease enter a scalar finite numeric value\n')
end
end
Rik
Rik le 9 Avr 2019
Thanks, my eyes must have skipped over the suggestion.
Also, that regexp is indeed what the better version of what the ismember should do.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Data Type Conversion dans Help Center et File Exchange

Tags

Produits


Version

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by