Smalltalk: how to check wether a string contains only numbers? - string

so basically I have some input possibilities for the user where should only numbers be accepted, otherwise the user will be alerted his input was incorrect.
the input is considered a String when I read it out using a callback.
now I want to check whether the string(which SHOULD contain numbers) actually DOES ONLY contain numbers, but I didnt find a solution implemented already.
i tried
theString isInteger
-is never true for the string
theString asNumber
- ignores letters, but I want to have a clear output wether letters are included in the string or not
theString isNumber
- always false

In Squeak and Pharo, you have the message #isAllDigits that does exactly what you want:
'1233248539487523' isAllDigits "--> true"

You can use a regular expression to check that the string contains only numbers:
theString matchesRegex: '\d+'
or a more complex regular expression to also allow an optional sign and decimal point:
theString matchesRegex: '-?\\d+(\\.\\d+)?'

Unfortunately, I could not locate messages 'isAllDigits' or 'matchesRegex'on Cincom Smalltalk.
However, what you could do is extract a word from the string and convert it to a number using asNumber.
So, if the returned value is 0(zero) it means that either the number is actually a 0(which could e checked with an additional condition) or string did not contain a digit/number.

This should work with many Smalltalks dialects:
(aString detect: [:c| c isDigit not ]) isNil ifTrue: [ "it's a number" ].

Related

Int32.TryParse equivalent for String?

I have been doing some homework. The task was to implement System.Int32.TryParse to check if an entered value is a number or something random. I was wondering if there is a built-in method that checks if something entered is a letter and NOT a number. I tried searching google and MSDN in the string type, but with no luck so far. I did write my own implementation, but I was curious.
Tnx
The easiest way to check whether a character is a number is probably to check whether it is in range from '0' to '9'. This works because of the way characters are encoded - the digits are encoded as a sub-range of the char values.
let str = "123"
let firstIsNumber =
str.[0] >= '0' && str.[0] <= '9'
This gives you a bit different behavior than Char.IsDigit because Char.IsDigit also returns true for thigns that are digits in other alphabets, say ႐႑႒႓႔႕႖႗႘႙ I suspect you do not plan to parse those :-).

Check if string contains 2 numbers

if PassField.Text:match("%a+%d%d+") or PassField.Text:match("%d%d+%a+") then
PWValid = true
else
return 'Error1'
end
This is my code so far but it's not too efficent because the string can be like bb1b12 so i would need to detect if the string contains 2 numbers anywhere
Two numbers is "some digits, then some non-digits, then some more digits". You don't need to care about anything else in string. Just use %d compliment - %D - it means exactly opposite of original. Also you probably should use find if you only want to test if string is valid or not.
str:find("%d+%D+%d+")

TryStrToFloat converts incorrect string

I'm using TryStrToFloat to convert string to Double variables. Everything works fine until string doesn't looks like '21e'. I get result of conversion 21.
It seems to me that compiler treats '21e' like number 21e0. String 21e1 gives result 210.
When I use Val function conversion works better. String '21e' gives error, but now '21e1' gives 210, '21e-1' gives number 2,1 etc.
How to make correct working of conversion. Should I detect letter 'e' in text, or is any simply way to convert ?
The documentation says:
Use TryStrToFloat to convert a string, S, to a floating-point value. S must consist of an optional sign (+ or -), a string of digits with an optional decimal point, and an optional mantissa. The mantissa consists of 'E' or 'e' followed by an optional sign (+ or -) and a whole number. Leading and trailing blanks are ignored.
Your input does not satisfy the conditions and so should be treated as an error.
You did not say so explicitly, but I presume that you claim that:
TryStrToFloat('21e', val)
returns True. If so, this is a bug and should be reported to Embarcadero. If you need to work around this then I suggest you code your own function that detects this case and handles it correctly.
On the other hand, if that function call returns False the function is behaving as designed and your mistake is to read the value in val.
Update
I can confirm that TryStrToFloat('21e', val) returns True. I tested on XE7 update 1. I submitted the following bug report to Embarcadero: https://quality.embarcadero.com/browse/RSP-9814

Checking if all letters in a string (from any major spoken language) are upper-casee

I simply want to check if all the letters that occur in a string are upper-case (if they have lower- and upper-case variants). Tcl's built-in procs don't behave quite as desired, e.g.,
string is upper "123A"
returns false, but I would want it to return true. I would also want it to return true if the A were replaced with, say, an upper-case Cyrillic letter, or a letter from another popular alphabet that doesn't have a case. I could simply filter out all non-letters from the string, but that's not so simple I think when you're trying to handle letters from languages other than just English.
In this case, you don't want string is upper as that checks if the string is just upper case letters. (Numbers aren't letters.)
Instead, you want to do:
set str "123A"
if {$str eq [string toupper $str]} {
# It's upper-case by your definition...
}

function to confirm the presence of both letters and numbers/ Ignoring excedents

So, I'm trying to build up a program with MATLAB according to some indications from my teacher and I came up with some obstacles which would give me a better grade if I could get them right. Here they are:
The user is asked to insert a string but it can't have more than 20 characters. If it does, the excedents will be ignored and the string is saved with the first 20 characters the user inserted. How do I ignore the excedents in a string and save it anyway?
isletter is a function that tells us if the elements are all letters. In this program, the user is asked to insert a string that needs to include both numbers and letters, so that strings with just letters or just numbers are excluded, and then I'll use a while to keep asking for a string with these characteristics.
Could you please help me? This is my first semester with MATLAB. Thank you!
If you want to disallow characters other than letters and numbers (i.e. '/#!' or whitespace) and require that the string they enter has to have at least 1 letter and 1 number, then you can use the ISSTRPROP function (which is more general than ISLETTER) to check for other types of characters. The idea to use INPUTDLG to prompt for the string (as suggested in Aabaz's answer) is a good one, so here's a nice condensed solution using INPUTDLG that achieves what you want:
answer = ''; %# Initialize answer to be an empty string
while any(~isstrprop(answer, 'alphanum')) || ... %# Check for alphanumeric chars
~any(isletter(answer)) || ... %# Check for at least 1 letter
~any(isstrprop(answer, 'digit')) %# Check for at least 1 number
answer = inputdlg('Enter string:'); %# Prompt for input
answer = answer{1}(1:min(20, end)); %# Trim answer to max of 20 chars
end
Note how the functions MIN and END are used to trim the string to 20 characters.
For the first part of your problem you can use the Matlab function inputdlg which prompts a dialog box asking for user input. Then you can trim the input as you like.
For the second part of your problem the function isletter that you mentioned will tell you for each character individually if they are alphabetic letters, so you could sum that result and check if it is between 1 and 19 for example. That will tell you that your string contains both letters and numbers.
Finally, you can put your code inside a while loop and change a variable when your conditions are met so that you can break outside of the loop.
This example code demonstrates this:
tryagain=1;
while(tryagain)
answer=inputdlg('Insert a 20 character string that contains both letters and numbers','User input');
answer=answer{1};
if(numel(answer)>20)
answer=answer(1:20);
end
letters=sum(isletter(answer));
numbers=sum(~arrayfun(#(x)isempty(str2num(x)),answer));
if(letters>0 && numbers>0)
tryagain=0;
end
end

Resources