How to compare string to integer with while do loop in pascal? - freepascal

How to compare string to integer using while loop in Pascal?
Like this:
var Destination:string;
while (Destination>'11') do begin
writeln('Error');
write('Destination Number');
readln(Destination);
end;

You have to convert Destination to an integer:
program Project1;
uses sysutils;
var
converted: integer;
Destination: string;
begin
converted := 12;
Destination := '';
while (converted > 11) do
begin
writeln('Error');
writeln('Destination Number');
readln(Destination);
converted := StrToIntDef(Destination, 12);
end;
end.
convertion routines are avalaible in sysutils:
http://www.freepascal.org/docs-html/rtl/sysutils/index-5.html

Why not just do the conversion in the WHILE--DO statement?
ReadLn(Destination);
WHILE StrToInt(Destination) > 11 DO NumberIsTooHigh;
where NumberIsTooHigh simply is a procedure you write to handle your "error". Ex:
PROCEDURE NumberIsTooHigh;
BEGIN
WriteLn('Your number is above valid range');
write('Destination Number');
readln(Destination);
END;
The reason for the previous routine to make "error" on the first run is that "Destination" does not yet have a value at all. The converted-variable is then set manually to 12, just outside the Ok-range, hence it will always produce the error on startup.

Related

How to automatic return value of "PI" from function without assign in operation part of function body

My code is under , i will be gratefull for any suggestion
(* //const
//pi=3.1415926;
//uses
//mathh.inc; *)
var
r,pole_kola,obwod_kola: real;
function Pi: valreal;
begin
Pi:=3.1415926;
end;
procedure dane();
begin
read(r);
end;
procedure obliczenia();
begin
pole_kola:= {pi}Pi*r*r;
obwod_kola:= 2*{pi}Pi*r;
end;
procedure wyniki();
begin
writeln('pole koła: ',pole_kola:4:8);
writeln('obwód koła: ',obwod_kola:4:8);
end;
begin
writeln('podaj promien r: ');
dane();
obliczenia();
wyniki();
end.
How i can use function Pi :
https://www.freepascal.org/docs-html/rtl/system/pi.html
to return automatic value of "PI" from function without assign in operation part of function body if i try modify function get back
Function result does not seem to be set
function Pi() :valreal;
begin
end;
begin
WriteLn('pi = ', Pi():1:20);
end.
Compiling main.pas
main.pas(1,10) Warning: Function result does not seem to be set
Linking a.out
8 lines compiled, 0.1 sec
1 warning(s) issued
pi = 0.00000000000000000000
in program
 ./main
podaj promien r:
6
pole koła: 0.00000000
obwód koła: 0.00000000

In the task, I wanted to automatically use a ready value for PI (3.14…) without using my function. My function didn’t returned a value because I didn’t assigned one. Like we see here:
function Pi() :valreal;
begin
//here is nothing but must be returned a value
end;
begin
WriteLn('pi = ', Pi():1:20);
end.
Going by #derpirscher’s comment, the function written by hand always needs to return something. So I commented part of my syntax, and used the built-in function named PI. (Pascal includes that function.)
(* function pi: valreal; // If I define my own function, it must return a value
begin
pi:=3.1415926; // So in the body of the function, we must assign value
end; *)
We see that here
procedure obliczenia();
begin
pole_kola:= {pi}Pi*r*r; // using build in function
obwod_kola:= 2*{pi}Pi*r; // as above
end;
If we need to use the value of PI in our task/homework, we can use predefinied built-in functions because it is easier; it is good practice to use less syntax in our code.
Must remember: If we define a function i.e., named Pi ourselves, it has to return a value.
Under the comment, the entire syntax of my code with corrections:
var
r,pole_kola,obwod_kola: real;
(* function pi: valreal; // If I define my own function, it must return a value
begin
pi:=3.1415926; // So in the body of the function, we must assign value
end; *)
procedure dane();
begin
read(r);
end;
procedure obliczenia();
begin
pole_kola:= {pi}Pi*r*r; // using build in function
obwod_kola:= 2*{pi}Pi*r; // as above
end;
procedure wyniki();
begin
writeln('pole koła: ',pole_kola:4:8);
writeln('obwód koła: ',obwod_kola:4:8);
end;
begin
writeln('podaj promien r: ');
dane();
obliczenia();
wyniki();
end.

Delphi JsonTextReader fails to read values

I have a very weird situation.
This is the JSON I am trying to parse:
[
{
"username":"xxx",
"email":"xxx#gmail.com",
"custom_title":"xxx title",
"timezone":"Africa\/Cairo",
"message_count":"218",
"alerts_unread":"0",
"like_count":"385",
"friend_count":"0"
}
]
This is my parsing code:
type
TUserData = record
email, timezone: string;
msg, alerts, likes: integer;
end;
procedure TDMRest.parseData(var b: TUserData);
var
jtr: TJsonTextReader;
sr: TStringReader;
begin
//RESTResponseLogin.Content has the above json text
sr := TStringReader.Create(RESTResponseLogin.Content);
try
jtr := TJsonTextReader.Create(sr);
try
while jtr.Read do
begin
if jtr.TokenType = TJsonToken.StartObject then
process(b, jtr);
end;
finally
jtr.Free;
end;
finally
sr.Free;
end;
end;
//here there is a problem
procedure TDMRest.process(var c: TUserData; jtr: TJsonTextReader);
begin
while jtr.Read do
begin
if (jtr.TokenType = TJsonToken.PropertyName) then
begin
if jtr.Value.ToString = 'email' then
begin
jtr.Read;
c.email := jtr.Value.AsString;
end;
if jtr.Value.ToString = 'timezone' then
begin
jtr.Read;
c.timezone := jtr.Value.AsString;
end;
if jtr.Value.ToString = 'message_count' then
begin
jtr.Read;
c.msg := jtr.Value.AsInteger;
end;
if jtr.TokenType = TJsonToken.EndObject then
begin
c.alerts := 0;
c.likes := 0;
exit;
end;
end;
end;
end;
MY PROBLEM: In the process() code, the first 2 if blocks (email and timezone) can read values into my record. But when I add other if blocks (like if jtr.Value.ToString = 'message_count' then), I cannot see the values of my record anymore.
Am I parsing the data properly?
Basically, I need to grab the info from a JSON string and put the data inside a TUserData record.
I have found the above pattern in a book titled "Expert Delphi", and I am pretty sure that the parseData() function is correct. Probably I am missing something in the process.
The TDMRrst is a DataModule; I am giving the function a record, and I'd like the data to be properly parsed.
What is wrong here?
In the JSON you have shown, all of the values are strings, there are no integers. So, when you call jtr.Value.AsInteger for the message_count value, it raises a conversion exception that you are not catching. TValue.AsInteger DOES NOT perform an implicit conversion from string to integer for you.
You will have to use jtr.Value.AsString instead and convert the string to an integer using StrToInt():
if jtr.Value.ToString = 'message_count' then
begin
jtr.Read;
//c.msg := jtr.Value.AsInteger;
c.msg := StrToInt(jtr.Value.AsString);
end;
Do the same for the other "integer" values in the JSON (alerts_unread, like_count, and friend_count).

Delphi 10, Digital Persona and MySQL

I am at my wits end at the moment. I have looked everywhere for a way of verifying a captured fingerprint in my MySQL database using the Digital Persona SDK(One Touch) and Delphi 10. I am able to save the fingerprint as a longblob in my database but I am unable to verify from my database. Hopefully someone here would be able to assist me. Reader is a U.Are.U 4500.
Below is the code I use to save the fingerprint, but I have no idea how to query the database when I need to verify the fingerprint again.
procedure TForm1.FPCaptureComplete(ASender: TObject;
const ReaderSerNum: WideString; const pSample: IDispatch);
var
l_interface : IDispatch;
outFile : File;
vt : integer ;
vtByteBuf : PByteArray;
aryLow : integer;
aryHigh : integer;
rawDataSize: integer;
loopIndex : integer;
begin
l_interface := FPGetImage.ConvertToPicture(pSample);
lblInfo.Caption:='Sample Captured';
SetOlePicture(pbPrint.Picture,IPictureDisp(l_interface)); //display print
if breginprogress=true then begin
if index > 4 then index:=1; //reset index if beyond 4 presses
if index=1 then
begin
lbl1.Font.Color:=clGreen;
lbl2.Font.Color:=clYellow;
end;
if index=2 then
begin
lbl2.Font.Color:=clGreen;
lbl3.Font.Color:=clYellow;
end;
if index=3 then
begin
lbl3.Font.Color:=clGreen;
lbl4.Font.Color:=clYellow;
end;
if index=4 then lbl4.Font.Color:=clGreen;
index := index + 1;
//Create registration\enrollment featureset from sample captured
try
FPExtraction.CreateFeatureSet(pSample,DataPurposeEnrollment);
except
on E: Exception do begin
showmessage('Exception inside CreateFeatureSet');
showmessage(E.Message);
FPregister.Clear;
ResetLabels;
index:=1;
exit;
end;
end;
if FPExtraction.FeatureSet <> nil then
//Add features to registration object
FPRegister.AddFeatures(FPExtraction.FeatureSet)
else begin
Showmessage('Could not create featureset, poor press');
FPRegister.Clear;
ResetLabels;
index:=1;
exit; //return
end;
//If 4 successful features added, status should be 'Ready'
if FPRegister.TemplateStatus=TemplateStatusTemplateReady then begin
lblResult.Caption:='User Enrolled - Press Finger for Verification';
lbl1.Visible:=false; lbl2.Visible:=false; lbl3.Visible:=false; lbl4.Visible:=false;
FPTemplate:=FPRegister.Template as DPFPShrXLib_TLB.DPFPTemplate;
breginprogress:=false; //stop registration process, enable verification
//Before saving data to database you will need to get the raw data (variant)
try
vrnt:=FPTemplate.Serialize; //raw data is now stored in this variant
aryLow:=VarArrayLowBound(vrnt,1);
aryHigh:=varArrayHighBound(vrnt,1);
aryHigh:=aryHigh-aryLow;
vtByteBuf:=VarArrayLock(vrnt); //lock down the array
for loopIndex := 0 to aryHigh - 1 do
fpData[loopIndex]:=vtByteBuf[loopIndex];
VarArrayUnlock(vrnt);
//Save fpData to database here
//Database logic is not provided here. Plenty examples on web on
//How to save a byte array (binary data) to database.
SaveFP;
except
on E: Exception do showmessage('Trouble saving data');
end;
end;
end;
end;
//This is the pysical save
procedure TForm1.SaveFP;
var
tptStream: TMemoryStream;
p: Pointer;
begin
MemberTbl.Insert;
MemberTbl.FieldByName('MemberName').AsString := NameEdit.Text;
tptStream := TMemoryStream.Create();
tptStream.Position := 0;
p := VarArrayLock(vrnt);
tptStream.Write(p^, VarArrayHighBound(vrnt, 1));
VarArrayUnlock(vrnt);
(MemberTbl.FieldByName('MemberFP') as BlobField).LoadFromStream(tptStream);
MemberTbl.Post;
tptStream.Free();
end;
I've created a component wrapper for the DigitalPersona One Touch for Windows SDK Version 1.6.1 (August 2010)
I've tested it with the DigitalPersona U.are.U 4000B reader, but according to the documentation, it should work with the DigitalPersona U.are.U 4500 reader too
You can have a look and download the component here
Then you can add code like this on the OnCaptured event handler:
procedure TForm1.DPFingerPrintReader1Captured(Reader: TDPFingerPrintReader; FingerComparer: IFingerComparer);
var
LFingerPrintField: TField;
begin
LFingerPrintField := YourDataSet.FieldByName('FingerPrintField');
while not YourDataSet.Eof do
begin
if FingerComparer.CompareTo(LFingerPrintField.AsString) then
begin
ShowMessage('Found');
Exit;
end;
YourDataSet.Next;
end;
ShowMessage('NOT Found');
end;

Encoding a message with Vigenere cipher in Delphi?

I want to encrypt a message with a simple Vigenere cipher by assigning each letter in the alphabet a numeric value e.g. A= 1; B= 2;..Z= 26. The problem is I don't know which function to use to recognize a character in a string(as it is a message that has to be encoded, complete with spaces), and then giving it a specific, numeric value.
Next up, that numeric message has to be converted into binary, which is easy, but how do I convert that message that was a string into an integer(other that the StrToInt function)?
I just need to know which function to use for the Vigenere Cipher.
*I am still in High school so I apologize in advance for using the wrong terms.
You can use a case statement to perform the encoding.
function EncodedChar(C: Char): Byte;
begin
case C of
'A'..'Z':
Result := 1 + ord(C) - ord('A');
' ':
Result := ???;
',':
Result := ???;
... // more cases here
else
raise ECannotEncodeThisCharacter.Create(...);
end;
end;
Encode a string with a for loop:
function EncodedString(const S: string): TBytes;
var
i: Integer;
begin
SetLength(Result, Length(S));
for i := 1 to Length(S) do begin
// dynamic arrays are 0-based, strings are 1-based, go figure!
Result[i-1] := EncodedChar(S[i]);
end;
end;

How to pass dynamic arrays in FreePascal correctly

In this FreePascal code I write, I found that in a dynamic array of length 'n', it always contained a random value in element 'n'.
I understand why that is, however, I am wondering if perhaps there is a flaw in the way i've written my code. I've pasted it below. I'd welcome any corrections.
program LinearSearch;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
{$R *.res}
type
ArrayOfByte = array of Byte;
Function findMaximum(studentMarks : ArrayOfByte; numberOfStudents : integer)
: integer;
var
maximumMark : Integer;
studentWithMaximumMark : Integer;
index : integer;
begin
setLength(studentMarks, numberOfStudents);
maximumMark := studentMarks[0];
for index:=0 to numberOfStudents do
begin
write(IntToStr(studentMarks[index]));
if index = numberOfStudents then writeln('.')
else write(',');
end;
for index:= 0 to (numberOfStudents - 1) do
begin
if studentMarks[index] > maximumMark then
begin
maximumMark := studentMarks[index];
studentWithMaximumMark := index;
end;
end;
write('Maximum score of ',IntToStr(maximumMark),' was achieved by ');
Result := studentWithMaximumMark+1;
end;
var
studentMarks : ArrayOfByte;
numberOfStudents : Integer;
studentWithMaximumMarks : Integer;
counter : integer;
begin
write('Enter the number of students: ' );
readln(numberOfStudents);
setLength(studentMarks,numberOfStudents);
writeln('Input the grades for the following students:');
for counter := 0 to (numberOfStudents - 1) do
begin
write('Student ',counter+1,': ');
readln(studentMarks[counter]);
end;
writeln('Data has been input. Finding student with maximum marks.');
studentWithMaximumMarks := findMaximum(studentMarks,numberOfStudents);
write('student no. ',IntToStr(studentWithMaximumMarks));
writeln;
writeln('Press ANY key to continue');
readln;
end.
In Free Pascal dynamic arrays are zero based. So the first element is MyArray[0] and last element is MyArray[High(MyArray)] which is equal to MyArray[Length(MyArray) - 1]. You should never access MyArray[Length(MyArray)].
...I found that in a dynamic array of length 'n', it always contained a random value in element 'n'. this is because you are accessing a value beyond of the bounds of the array, check in the procedure findMaximum the line
for index:=0 to numberOfStudents do
must be
for index:=0 to numberOfStudents-1 do
Also you can remove the first line of the same procedure setLength(studentMarks, numberOfStudents);