Using Localhost in Delphi - lazarus

Evening everyone,
The ideology was given yesterday so, i have been taking my time to learn delphi.
I want to send data vis URL (using GET request / Wininet) now i have problems using the http://localhost in delphi program, as when i try to use the localhost like this http://localhost, it comments the other instructions to be concatenated
I am using Lazarus , and my code goes like this
program InfoWininet;
{$mode delphi}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes , Windows , Wininet
{ you can add units after this };
var
FirstName : string;
LastName: string;
Email: string ;
IDNumber: string;
IOpen, IURL: HINTERNET;
Read: Cardinal;
data: string;
Result : string;
http : HINTERNET;
begin
Writeln('Enter Your First Name: ');
Readln(FirstName);
Writeln('Enter your Last Name: ');
Readln(LastName);
Writeln('Enter Your Email: ');
Readln(Email);
Writeln('Enter your ID Number: ');
Readln(IDNumber);
data := http://localhost/data.php?fname=' + FirstName + '&lastName=' + LastName + '&Email=' + Email + '&IdNumber=' + IDNumber;
begin
Result:='';
try
IOpen := InternetOpen('Oxysys',INTERNET_OPEN_TYPE_PRECONFIG, '', '',INTERNET_FLAG_NEED_FILE);
if IOpen<>nil then
try
IURL:= InternetOpenUrl(IOpen, data, nil, 0,INTERNET_FLAG_DONT_CACHE, 0);
if IURL<> nil then
try
SetLength(data,4096);
repeat
if InternetReadFile(IURL,#data[1],4096,Read) then
Result:=Result + Copy(data,1,Read)
else
Break;
until Read = 0;
finally
InternetCloseHandle(IURL);
end;
finally
InternetCloseHandle(IOpen);
end;
except
end;
Writeln('Message Sent Successfully...');
Readln;
end;
end.
Question is i get the following errors, when trying to compile my program
InfoWininet.lpr(33,13) Warning: Variable "http" does not seem to be initialized
InfoWininet.lpr(33,13) Error: Incompatible types: got "Pointer" expected "AnsiString"
InfoWininet.lpr(33,17) Fatal: Syntax error, ";" expected but ":" found
What could really be the problem? Can someone pls help, in correcting the problem, pls Am trying to learn Delphi Very well.

data := http://localhost/data.php?fname=' + FirstName + '&lastName=' + LastName +
'&Email=' + Email + '&IdNumber=' + IDNumber;
You have failed to wrap your string literal in quotes. It should be:
data := 'http://localhost/data.php?fname=' + ....
^
quote missing here

Related

Incompatible types: 'string' and 'Boolean' [duplicate]

This question already has answers here:
Incompatible types: 'string' and 'Double'
(2 answers)
Closed last year.
I have to check for a sound card, so I don't need quality but only one answer yes or no. I used this code:
function IsSoundCardInstalled: Boolean;
Begin
Result := waveOutGetNumDevs > 0;
End;
procedure TForm1.FormCreate(Sender: TObject);
var
ids: TidIpWatch;
Speed: Double;
myStringList: TStringList;
begin
ids := TidIpWatch.Create;
Speed := GetCPUSpeed;
ids.Free;
myStringList:=TStringList.Create;
myStringList.Add('IP:' + (ids.LocalIP));
myStringList.Add('CPU: ' + (Tipo_cpu) + ' ' + Format('%f', [Speed]));
myStringList.Add((IsSoundCardInstalled));
myStringList.Add('etc.');
Memo1.Lines.Assign(myStringList);
myStringList.Free;
end;
But the error returns to me:
[DCC Error] Unit1.pas(138): E2010 Incompatible types: 'string' and 'Boolean'
On the line:
myStringList.Add((IsSoundCardInstalled));
IsSoundCardInstalled() returns a Boolean, but myStringList.Add() expects a string instead. You can't assign a Boolean as-is to a string, you need to use a conversion function (just like in your previous question), such as SysUtils.BoolToStr():
uses
..., SysUtils;
myStringList.Add(BoolToStr(IsSoundCardInstalled));
Or SysUtils.TBooleanHelper.ToString() in XE4+:
uses
..., SysUtils;
myStringList.Add(IsSoundCardInstalled.ToString);
On a side note: you are freeing the TIdIPWatch component before reading its LocalIP property, which is undefined behavior.
For that matter, you should not be using TIdIPWatch in this manner at all. It is meant for notifying you when the local IP changes, and for maintaining a history of local IP changes over time, but that is not how you have been using it lately. The TIdIPWatch.LocalIP property simply reads the global GStack.LocalAddress property, that is what you should be using instead:
uses
..., IdStack;
TIdStack.IncUsage;
try
myStringList.Add('IP:' + GStack.LocalAddress);
finally
TIdStack.DecUsage;
end;
However, a machine can have multiple local IPs, so you really should use GStack.GetLocalAddressList() instead:
uses
..., IdStack;
var
myLocalIPList: TIdStackLocalAddressList;
i: Integer;
begin
...
TIdStack.IncUsage;
try
myLocalIPList := TIdStackLocalAddressList.Create;
try
GStack.GetLocalAddressList(myLocalIPList);
for I := 0 to myLocalIPList.Count-1 do
myStringList.Add('IP:' + myLocalIPList[I].IPAddress);
finally
list.Free;
end;
finally
TIdStack.DecUsage;
end;
...
end;

Not overloading operator

Good day, I'm doing some Codeforces exercises in my free time, and I had a problem to test if the user was a boy or a girl, well, my problem isn't that, i have just demonstrated the code.
While compiling my code in my computer ( I'm using version 3.0.4 for i386 ) i get no error, but codeforces gives me this error
program.pas(15,16) Error: Operator is not overloaded: "freq(Char;AnsiString):LongInt;" + "ShortInt"
program.pas(46,4) Fatal: There were 1 errors compiling module, stopping
The error wasn't clear enough to me, as the same script was perfectly compiled with my version.
The platform is using ( version 3.0.2 i386-Win32 ).
program A236;
uses wincrt, sysutils;
var
username : String;
function freq(char: char; username : String): Integer;
var
i: Integer;
begin
freq:= 0;
for i:= 1 to length(username) do
if char = username[i] then
freq:= freq + 1;
//writeln(freq);
end;
function OddUserName(username : String): Boolean;
var
i, counter: Integer;
begin
OddUserName:= false; // even
counter:= 0;
for i:= 1 to length(username) do
if freq(username[i], username) <> 1 then
delete(username, i, 1)
else
counter:= counter + 1;
if counter mod 2 <> 0 then
OddUserName:= true; // odd
//writeln(counter);
//writeln(OddUserName);
end;
begin
readln(username);
if not OddUserName(username) then
writeln('CHAT WITH HER!')
else
writeln('IGNORE HIM!');
//readkey();
end.
The error is supposed to be at this line probably :
function freq(character: char; username : String): Integer;
Thanks for everyone who helps.
Inside of a function, the function's name can be used as a substitute for using an explicit local variable or Result. freq() and OddUserName() are both doing that, but only freq() is using the function name as an operand on the right-hand side of an assignment. freq := freq + 1; should be a legal statement in modern Pascal compilers, see Why i can use function name in pascal as variable name without definition?.
However, it would seem the error message is suggesting that the failing compiler is treating freq in the statement freg + 1 as a function type and not as a local variable. That would explain why it is complaining about not being able to add a ShortInt with a function type.
So, you will have to use an explicit local variable instead, (or the special Result variable, if your compiler provides that), eg:
function freq(charToFind: char; username : String): Integer;
var
i, f: Integer;
begin
f := 0;
for i := 1 to Length(username) do
if charToFind = username[i] then
f := f + 1;
//writeln(f);
freq := f;
end;
function freq(charToFind: char; username : String): Integer;
var
i: Integer;
begin
Result := 0;
for i := 1 to Length(username) do
if charToFind = username[i] then
Result := Result + 1;
//writeln(f);
end;

Using TIdHTTPServer thread safe in D2005

This question has been asked very often and I've spent hours reading, trying, testing with no result.
I guess it has to do with my older 2005 version.
Below is the code I tried after reading a post in the Embarcadero forum answered by Remy Lebeau:
Thread: How to handle multiple HTTP sessions with Indy10 TIdHTTPServer
procedure TMainForm.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
Msg : String;
begin
if ARequestInfo.QueryParams <> '' then
begin
Msg := DateTimeToStr(Now) + ': ReqParam "' + ARequestInfo.QueryParams + '"';
TThread.Queue(nil,
procedure
begin
Memo1.Lines.Add(Msg);
end
);
AResponseInfo.ContentText := '<HTML><BODY>Query Params found.</BODY></HTML>';
end
else
begin
AResponseInfo.ContentText := '<HTML><BODY>Error: No Query Params.</BODY></HTML>';
Msg := DateTimeToStr(Now) + ': Error: No Query Params';
TThread.Queue(nil,
procedure
begin
Memo1.Lines.Add(Msg);
end
);
end;
end;
What I'm aiming for is accessing a memo or log file entry in a thread safe manner. Somehow using TThread.Synchronize() or TThread.Queue() doesn’t compile.
When adding the TThread.Queue() line as suggested by Remy, the error I get is:
E2029 Expression expected but procedure found
Does somebody have an alternative that I can use in Delphi 2005?
Edit: this is what I see from code completion:

Pascal - Writing Strange Characters

I am attempting to write a comment stripper in pascal. I run my code and pass it a C source code file and it strips the comments from the file and prints the result to terminal.
I am fairly new to pascal. I am getting some very strange output and I cannot figure out why. The code checks for comments line by line and prints characters one at a time. The comment stripper is printing what seems to be random characters whenever it reaches the start of a new line. I am using pascals Write(Str[i]) function to print characters and WriteLn() once the end of a line is reached.
I have no idea why im receiving weird output. I am running Linux Mint and can compile and run my code, but I receive this strange output. I also tried running my code on a Mac and received a run-time error:
Program Path: ./Assignment1
File Name: lol.c
Runtime error 2 at $00011532
$00011532
$0002F7F6
$000113FD
$00011328
$00000002
Here is my code
program Assignment1;
uses
Sysutils;
var UserFile : TextFile;
TString : String;
OLine : String;
i : integer;
isComment : boolean;
skip : boolean;
begin
{$I+}
WriteLn('Program Path: ', ParamStr(0));
WriteLn('File Name: ', ParamStr(1));
Assign(UserFile, ParamStr(1) + '.c');
Reset(UserFile);
isComment := false;
skip := true;
Repeat
Readln(UserFile, TString);
for i:= 0 to ((Length(TString) - 1)) do
begin
if(skip) then
begin
skip := false;
continue;
end;
if(isComment = false) Then
begin
if(TString[i] = '/') Then
begin
if(TString[i+1] = '/') Then
begin
break;
end
else if(TString[i+1] = '*') Then
begin
isComment := true;
skip := true;
continue;
end;
end;
Write(TString[i]);
if(i = Length(TString) - 1) Then
begin
Write(TString[i + 1]);
end;
end
else
begin
if(TString[i] = '*') Then
begin
if(TString[i + 1] = '/') Then
begin
isComment := false;
skip := true;
continue;
end;
end;
end;
end;
WriteLn();
Until Eof(UserFile);
end.
I receive random characters which range from standard keyboard symbols to unicode blocks such as the ones found here.
Does anyone have any suggestions?
As 500 - Internal Server Error says, Pascal strings are 1-based. Your references to slot zero are returning garbage. If these are 256-byte strings you're getting the length code, I don't recall the memory layout of the pointer-based strings to know what you're getting in that case. You're also losing the last character of every string because of this.
Beyond that I see a definite bug: Look at what happens with a line ending in /
I also do not understand this:
if(i = Length(TString) - 1) Then
begin
Write(TString[i + 1]);
end;
It seems to me it's writing an extra character but I'm not sure.

how to get a variable out of a procedure in the right way in PASCAL?

I'm following an internet course on the basics of programming. After making a diagram I convert it to code, right now this is PASCAL language.
I'm having a problem with procedures and can't find an answer, nor in the course, nor with some google-ing.
I want to get a variavble back form a procedure. Right now iIhave a working piece of code but I think this is not the good way of working. Here's an extract of the code:
program WELKEWAGEN;
// declare your variables here
var T, N, KM, vari, prijsDW, prijsBW, jrenGEBR, taksDW, taksBW, prijsB, verbrBW, prijsD, verbrDW : real;
procedure OPHALEN(para : string);
begin
repeat
writeln('geef de ', para , ' op');
readln(vari);
until (vari > 0);
end;
begin
//this is the main program but there is more code ofcourse
OPHALEN('prijs benzinewagen');
prijsBW := vari;
//...
end.
Now the internet course says I should program it like this:
begin
//...
prijsBW := OPHALEN('prijs benzinewagen');
//...
end.
But this is not working.
I get following errors:
WELKEWAGEN.pas(24,14) Error: Incompatible types: got "untyped" expected "Real"
WELKEWAGEN.pas(50) Fatal: There were 1 errors compiling module, stopping
pas(24,14) is this line: prijsBW := OPHALEN('prijs benzinewagen');
Procedures don't return values, so the syntax
prijsBW := OPHALEN('prijs benzinewagen');
is invalid.
If you want to return a value, you need to define a function instead:
function OPHALEN(para : string): Real;
var
Res: Real;
begin
Res := 0;
repeat
writeln('geef de ', para , ' op');
readln(Res);
until (Res > 0);
OPHALEN := Res;
end;
Note that the (bad) global variables you're using mean you don't have to return anything at all, because a procedure can access and change that global variable directly (but you have no way of knowing when the procedure is finished):
procedure OPHALEN(para : string);
begin
vari := 0;
repeat
writeln('geef de ', para , ' op');
readln(vari);
until (vari > 0);
end;
Modern Pascal dialects (such as Delphi and FreePascal) allow a cleaner syntax for the return value of functions by using an automatically declared function result variable of the proper type for you, named Result (because that's what it is - the result of the function):
function OPHALEN(para : string): Real;
begin
Result := 0;
repeat
writeln('geef de ', para , ' op');
readln(Result);
until (Result > 0);
end;
If you need to return multiple values, you can use var parameters, which allow them to be changed inside the function.
procedure OPHALEN(para: string; var RetVal: Real);
begin
RetVal := 0;
repeat
writeln('geef de ', para , ' op');
readln(RetVal);
until (RetVal > 0);
end;
Your original code (and the examples I've provided above) all fail to allow the user to cancel, BTW. There should be some way to exit the loop for the user; otherwise, your code just endlessly loops, writing para to the screen and then waiting for input. This has a tendency to annoy users.

Resources