Can I use an If statement inside a While statement? - delphi

while not eof(MyFile) do
begin
Readln(MyFile,sLine);
iCheck := pos('*',sLine);
if iCheck >= 0 then
K := K + 1;
else
K := 1;
sLine := sArrayParty[K];
end;
K is my counter. MyFile is set to a textfile.
I am trying to run an if statement inside a while statement to check if there is a * in a line read into sLine. If so, I want my counter to be incremented, thereby putting the following text into the next index of the array. So basically I have a text file with information separated by * as delimiters and I want each piece of information to populate a new index. But delphi spases everytime I put that if statement in.

You have a clear syntax error in your code, and the compiler explains exactly what it is:
[DCC Error] Unit1.pas(22): E2153 ';' not allowed before 'ELSE'
So read the words the error message contain, and remove the ; before the else:
if iCheck > 0 then
K := K + 1
else
K := 1;
The number in parenthesis after the Unit1.pas (in my example, (22) is the exact line number where the compiler stopped working, so the line before the else would be line 21. The line numbers at the bottom of the editor window tell you what line that is clearly.

if there is no '' then the pos function will return 0,
if there is '' then it will return the first occurance position.
if iCheck >= 0 then
should be changed to if iCheck > 0 then

i do remember we can assign the string to a string list and assign the stringlist's delimiter property to '*'
ie.
strlst.delimiter := '*';
strlst.text := sline;
so u can get each string traversing through the strlst...
(i used this long back,and i dont have delphi now to test it,please correct me if any thing is wrong)

Related

Is there a way to set a minimum number of characters that can be inserted in an edit in Delphi?

The minimum number of characters that can be inserted in an edit is 10, I used this code but nevertheless the message keeps saying that there is not enough characters.
ilength := length(sDetails);
if (ilength IN [0..9] )
then showmessage('You have to insert more than 10 characters') else showmessage('Thank you') ;
You did not show how you are assigning sDetails or what it actually contains when you get the wrong message displayed. However, you should not be using the in iterator to check the length, use arithmetic operators instead, eg:
ilength := Length(sDetails);
if ilength < 10 then
ShowMessage('You have to insert 10 or more characters')
else
ShowMessage('Thank you');

Retrieving second word to last but one word in a sentence in plsql

I have written a program which executes properly in plsql but the output is wrong. Logically I donot see any issue with the code. Here is the code:
begin
inpstr := rtrim(ltrim(regexp_replace(inp,'\s{2,}','')));
lastpos := instr(inpstr,' ',-1);
out3 := SUBSTR(inpstr, INSTR(inpstr,' ',-1) + 1);
pos := instr(inpstr,' ');
out1 := substr(inpstr,1,pos);
out2 := substr(inpstr,pos,lastpos);
end;
O/P:
dbms_output.put_line('First Word:: '||out1||' '||'Second Word:: '||out2||' '||'Lastword:: '||out3);
PROCEDURE SPLITWORDS compiled
anonymous block completed
First Word:: Welcome Second Word:: to the world of analyti Lastword:: analytics!
But the second word should retrieve 'to the world of' but it fetches analyti.
Could anyone tell me whats wrong with my code.
Thanks,
Dex.
When you assign out2, you at least have to substract pos from lastPos.
Because lastPos in your sample-text "Welcome to the world of analytics!" will be 24 and pos will have 8, so the substring from pos 8 with a length of 24 is ... right: " to the world of analyti"
The third parameter of the substr function is the length of the substring, not the location of the ending character. Subtracting pos from lastpos (see below) would allow your code to work.
out2 := substr(inpstr, pos, lastpos - pos);

Algol60 passing integer element of array as parameter - error bad type

I have following problem.
When I try to run the code with arun file.obj (I have compiled with algol.exe file)
BEGIN
INTEGER PROCEDURE fun(tab,index,lower,upper);
INTEGER tab,index,lower,upper;
BEGIN
INTEGER t;
text (1, "Start");
t := 0;
FOR index := lower STEP 1 UNTIL upper DO
t := t + tab;
fun := t;
END;
INTEGER ARRAY t[1:10];
INTEGER i,result,lower,upper;
lower := 1;
upper := 10;
FOR i := 1 STEP 1 UNTIL 10 DO
t[i] := i;
i := 1;
result := fun(t[i],i,lower,upper);
END FINISH;
I am still getting error:
ERROR 3
ADD PBASE PROC LOC
07D4 0886 1 13
083A 0842 0 115
The compiler I use is "The Rogalgol Algol60" product of RHA (Minisystems) Ltd.
Error 3 means "3 Procedure called where the actual and the formal parameter types do not match."
But I do not understand why. The reason of error is t[i] (If I change to i - it is ok).
Someone knows what I am doing wrongly?
I compile the code on the dosbox (linux)
Problem is that the index of the integer array that you're passing to your procedure isn't the same as the integer that he's expecting. I can't remember what an integer array is full of, but I guess it isn't integers... Have to admit I never use them, but can't remember why. Possibly because of limitations like this. I stick to Real arrays and EBCDIC ones.
You can almost certainly fix it by defining a new integer, j; inserting "j := t[i];" before your invocation of 'fun'; then invoking 'fun' with 'j' rather than t[i].
BTW you may want to make the array (and the 'for' loop) zero-relative. ALGOL is mostly zero-relative and I think it may save memory if you go with the flow.
Let me know if this helps....

Searching a sorted TStringList for an entry with a prefix (StartsText)

I have a TStringList which is sorted and contains unique filenames. The list can be of any size (so it can be hundreds of thousands of entries). I want to check to see if any of the entries start with a particular string (i.e. if the files are in a sub-folder). It's easy enough serially scanning the list and using StartsText, but that isn't an ideal solution.
Using the TStringList.Find() code as a starting point, I've created a function which I think is the solution, but I want to be sure. Don't worry about the following not being a member of the class (FList is the TStringList instance being searched), and StartsFilename works the same way as StartsText:
function ShortcutFind(const S: string): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
L := 0;
H := FList.Count - 1;
while L <= H do begin
I := (L + H) shr 1;
if TFilenameUtils.StartsFilename(FList[I], aFolder) then begin
Result:=TRUE;
Exit;
end;
C := FList.CompareStrings(FList[I], S);
if C < 0 then
L := I + 1
else begin
H := I - 1;
if C = 0 then begin
Result := True;
if FList.Duplicates <> dupAccept then L := I;
end;
end;
end;
end;
Basically, the only real change is that it does the check before moving onto the next entry to compare.
Note that switching from TStringList is not an option.
Would this method work?
Thanks
If TFilenameUtils.StartsFilename is the same as StartsText (and your first paragraph suggests it might be), then you can do the whole function in one statement by using TStringList.Find instead of copying it:
var
I: Integer;
begin
Assert(not FList.CaseSensitive);
Result := FList.Find(S, I) or ((I < FList.Count) and StartsText(S, FList[I]));
end;
That should work because when Find fails, it still tells you the index of where the desired string would have appeared in the list. When you search for your prefix string, its location will be before any other strings that start with that prefix, so if there are any strings with that prefix, they'll appear immediately after the hypothetical location of the prefix itself.
If you want to keep your current code, then you can simplify it by removing the conditional that checks C = 0. That condition should never occur, unless your StartsFilename function is broken. But, if the function really is broken and C can be zero, then you can at least stop executing the loop at that point since you've found what you were looking for. Either way, you don't need to check Duplicates since your function doesn't have the same requirement as Find does to return the index of the found item.

TStringList problem with values at index

So I have several summary files that I want to read and get the values from.
I am doing the following:
OutputSummary := TStringList.Create;
for idx := 0 to 82 do
OutputSummary.Insert(idx, '');
to initialize the values I'm using
then, I have a loop:
for idx := 0 to SummaryFiles.Count - 1 do
begin
AssignFile(finp, SummaryFiles[idx]);
ReSet(finp);
for ndx := 0 to 5 do
ReadLn(finp, buff);
for ndx := 0 to 82 do
begin
ReadLn(finp, buff);
temp := GetToken(buff, ' ');
buff := GetRemains(buff, '|');
temp := GetToken(buff, '|');
valuestring := OutputSummary[ndx] + delimiter + temp;
OutputSummary.Insert(ndx, valuestring);
end;
CloseFile(finp);
end;
The first 0 to 5 loop skips the lines I don't want to read, and the 0 to 82 reads lines that look like
1. Initial Wait List|1770
So I was debugging the program to see how it works with just 2 SummaryFiles.
The first time through, it works perfectly. The line is read correctly, I get the value and when I insert valuestring, it looks like ",1770" (for example), and I can also highlight OutputSummary[ndx] after the insert command and see that the value was inserted correctly.
Then I open the second file, which also works fine until the line
valuestring := OutputSummary[ndx] + delimiter + temp;
the first time, OutputSummary[0] is correct and the correct line is added.
However, OutputSummary[1] through OutputSummary[82] is the same as OutputSummary[0]! This makes no sense since when I was first adding those values, I could see that OutputSummary[1] through 82 were unique and correct.
Can anyone see a problem? Is it a debugger error? Am I just missing something obvious that I don't see?
thanks
It looks to me like you're trying to create a table of some sort, with one column per input file and one row per line in the file, with the columns separated by the delimiter. If so, calling .Insert on the string list isn't going to quite work right, since you'll end up inserting 83 * SummaryFiles.Count rows.
Instead of the Insert call, you need something like this:
if OutputSummary.count > ndx then
OutputSummary[ndx] := valuestring
else OutputSummary.Add(valuestring);
See if that helps.
Also, you might want to consider replacing the "magic number" 82 with a meaningful constant, like const LINES_TO_READ = 82. That makes it easier to read the code and understand what it's supposed to be doing.

Resources