Nikolas Nikolas - 2 months ago 22
Pascal Question

Turbo Pascal: check if string contains numbers

As it's said in the title Im having trouble finding a solution on how to check if a string

PW
contains a number or not. How can i check in TP if the string
PW
contains a digit?

repeat
writeln;
writeln('Ok, please enter your future password.');
writeln('Attention: The Text can only be decoded with the same PW');
readln(PW);
pwLength:= Length(PW);
error:=0;
for i:= 1 to Length(PW) do begin
if Input[i] in ['0'..'9'] then begin
error:=1;
end;
end;

if Length(PW)=0 then
begin
error:=1;
end;

if Length(PW)>25 then
begin
error:=1;
end;

if error=1 then
begin
writeln('ERROR: Your PW has to contain at least 1character, no numbers and has to be under 25characters long.');
readln;
clrscr;
end;

until error=0;

Answer

This is how I would write your code:

var
  PW : String;
  Error : Integer;

const
  PWIsOk = 0;
  PWIsBlank = 1;
  PWTooLong = 2;
  PWContainsDigit = 3;

procedure CheckPassword;
var
  i : Integer;
begin

  writeln;
  writeln('Ok, please enter your future password.');
  writeln('Attention: The Text can only be decoded with the same PW');
  writeln('Your password must be between 1 and 25 characters long and contain no digits.');

  repeat
    error := PWIsOk;
    readln(PW);

    if Length(PW) = 0 then
      Error := PWIsBlank;

    if Error = PWIsOk then begin
      if Length(PW) > 25 then
        Error := PWTooLong;
      if Error = 0 then begin
        for i := 1 to Length(PW) do begin
          if (PW[i] in ['0'..'9']) then begin
            Error := PWContainsDigit;
            Break;
          end;
        end;
      end;
    end;

    case Error of
      PWIsOK : writeln('Password is ok.');
      PWIsBlank : writeln('Password cannot be blank.');
      PWTooLong : writeln('Password is too long.');
      PWContainsDigit : writeln('Password should not contain a digit');
    end; { case}
  until Error = PWIsOk;
  writeln('Done');
end;

These are some of the things to notice:

  • Don't use the same error code value to represent different types of error. Using the same value for different errors just makes it more difficult for you to debug your code, because you can't tell which test gave Error the value 1.

  • Define constants to represent the different types of error. That way, readers don't have to wonder "What does 3 mean" in if error = 3 ...

  • Once you've detected a digit character in the password, there is no point examining the characters after it, hence the Break in my for loop.

  • If I were a user I would be annoyed not to be told what the rules are until after the program tells me I've done something wrong. Tell the use beforehand what the rules are.

  • Actually, it would be better to include an additional constant Unclassified with a value of say, -1, and start each iteration of the loop by assigning Error to it and, in the subsequent steps, test for Error = Unclassified rather than PWIsOk.

  • A case statement is a tidy and easily-maintainable way of selecting one of a number of mutually exclusive execution paths based on an ordinal value.