Pascal compilation error - pascal

This is the code:
program pi18;
var
a,b,c,P:real;
begin
read(a,b,c);
if(a+b<c) or (b+c<a) or (a+c<b) then
writeln('Nu exista asa triunghi')
else
begin
P:=a+b+c;
if(a=b) and (a=c) then
write('Triunghiul este echil')
else
if(sqr(a) = sqr(b) + sqr(c)) or (sqr(b) = sqr(a) + sqr(c)) or (sqr(c) = sqr(a) + sqr(b)) then
write('Triunghiul este dreptunghic'); readln();
else
write('Triunghiul este arbitrar'); readln();
end;
writeln('Perimetrul este: ', P);
end.
And I have this error:
Syntax error, ";" expected but "ELSE" found
This code is for:
- says the perimeter of a triangle.
- compare if the a,b,c are numbers for some types of triangles.

If you want to execute multiple statements when a condition is true, you need to wrap them with begin and end. Putting them on the same line doesn't automatically group them. So you need begin and end around:
write('Triunghiul este dreptunghic'); readln();
and
write('Triunghiul este arbitrar'); readln();
Since you didn't do this, it just processes the first statement as the if block. When it sees the else statement, it reports an error because there's no preceding if statement to match it with.

In Pascal if you have multiple statements between then and else you still need to put begin and end around them:
if(sqr(a) = sqr(b) + sqr(c)) or (sqr(b) = sqr(a) + sqr(c)) or (sqr(c) = sqr(a) + sqr(b)) then
begin
write('Triunghiul este dreptunghic');
readln();
end
else

Your code lacks begin-end around the multiple statements following if:
if(a=b) and (a=c) then
write('Triunghiul este echil') // single statement, no begin-end required (but possible)
else if(sqr(a) = sqr(b) + sqr(c)) or (sqr(b) = sqr(a) + sqr(c)) or (sqr(c) = sqr(a) + sqr(b)) then
begin
write('Triunghiul este dreptunghic');
readln();
end
else
begin
write('Triunghiul este arbitrar');
readln();
end;
To make this more consistent, I would even do:
if(a=b) and (a=c) then
begin
write('Triunghiul este echil')
end
else etc...

Related

Program in pascal [duplicate]

This question already has answers here:
What is that the Error of Illegal assignment and how to correct it?
(2 answers)
Closed last month.
Just started to learn the Pascal programming language, I wrote an assignment that was given at the university, here is my assignment:
Build a program that will perform the following actions:
retrieve data of N elements (brand, name, atomic weight, density)
find the average density value
finding the three elements with the lowest atomic mass
writing the inputs and outputs to the text file "elements.txt"
wrote code for it, in theory everything should work, but it gives out some strange errors, if I have standard errors, I apologize for them.
program MINERALY_;
uses Crt;
const NMAX=200;
type MINERAL=record
NAZOV:string;
HUST:real;
ATOM:real;
ZNACKA:real;
end;
MINERALY=array[1..NMAX] of MINERAL;
var N,i,C,D:integer;
V:real;
MI:MINERALY;
S:string;
SUB:text;
PTVRD,CTVRD:real;
MINATOM:real;
begin
ClrScr;
Writeln('Program pre nacitanie mineralov a vypocet hodnot ich jednotlivych
vlastnosti.');
Writeln('===============================================================================');
{Vynulovanie hodnot}
CTVRD:=0;
PTVRD:=0;
MINATOM:=0;
{Nacitanie poctu mineralov}
Writeln;
Write('Zadajte pocet nacitavanych mineralov (Maximalne 200): ');
repeat
Readln(S);
Val(S,D,C);
if (C<>0) or (D<=0) or (D>200) then
begin
Writeln;
Writeln('Zadali ste nespravny pocet, alebo ste zadali nespravne znaky !');
Writeln('Hodnota moze byt od 1-200');
Write('Zadajte pocet mineralov este raz: ');
end;
N:=D;
until(N>0) and (N<=200) and (C=0);
{nacitavanie udajov, zistovanie max. a min. hodnot atd.}
for i:=1 to N do
begin
Writeln;
Write('Zadajte Znacku: ');
Readln(MI[i].ZNACKA);
Writeln;
Write('Zadajte nazov: ');
Readln(MI[i].NAZOV);
Write('Zadajte hustotu (musi byt vacsia ako 0): ');
repeat
Readln(S);
Val(S,V,C);
if (C<>0) or (V<0) then
begin
Writeln;
Writeln('Zadali ste nespravnu hodnotu, alebo ste zadali nespravne znaky !');
Write('Zadajte hustotu este raz (musi byt vacsia ako 0): ');
end;
until (V>0) and (C=0);
MI[i].HUST:=V;
CTVRD:=CTVRD+MI[i].HUST;
Write('Zadajte atómovou hmotnosťou (musi byt vacsia ako 0): ');
repeat
Readln(S);
Val(S,V,C);
if (C<>0) or (V<0) then
begin
Writeln;
Writeln('Zadali ste nespravnu hodnotu, alebo ste zadali nespravne znaky !');
Write('Zadajte atómovou hmotnosťou este raz (musi byt vascia ako 0): ');
end;
until (V>0) and (C=0);
MI[i].ATOM:=V;
if (i=1) then MINATOM:=MI[i].ATOM;
if (MI[i].ATOM<MINATOM) then MINATOM:=MI[i].ATOM;
PTVRD:=CTVRD/N;
Writeln;
Writeln('Vypocitane hodnoty: ');
Writeln('===================================');
Writeln;
Writeln('Priemerna tvrdost mineralov: ',PTVRD:2:2);
Writeln('Najnizsia hustota: ',MINATOM:2:2);
Assign(SUB,'mineral.txt');
Rewrite(SUB);
Writeln(SUB,'Nacitane mineraly: ');
Writeln(SUB,'===================================');
Writeln(SUB,'');
for i:=1 to N do
begin
Writeln(SUB,i,'. mineral: ');
Writeln(SUB,'Nazov: ',MI[i].NAZOV);
Writeln(SUB,'Znacka: ',MI[i].ZNACKA);
Writeln(SUB,'Tvrdost: ',MI[i].HUST:2:2);
Writeln(SUB,'Hustota: ',MI[i].ATOM:2:2);
Writeln(SUB,'');
end;
Writeln(SUB,'===================================');
Writeln(SUB,'Vypocitane hodnoty: ');
Writeln(SUB,'===================================');
Writeln(SUB,'');
Writeln(SUB,'Priemerna tvrdost mineralov: ',PTVRD:2:2);
Writeln(SUB,'Najnizsia hustota: ',MINATOM:2:2);
Close(SUB);
Writeln;
Writeln;
Writeln('Pre ukoncenie programu stlacte ENTER !');
Readln;
end.
Here are the errors this code gives me:
Compiling main.pas
main.pas(109,14) Error: Illegal assignment to for-loop variable "i"
main.pas(132,4) Fatal: Syntax error, ";" expected but "." found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Error: Illegal assignment to for-loop variable "i"
is when you are trying to change the value of i while the loop is still working.
since you didn't end; the loop you canno't change the value of i you can use another variable, j for example, unless your first for-loop is over and you forgot the end; key

Is there a better way to program this,

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Numerics.Float_Random;
with Ada.Numerics.Discrete_Random;
procedure Probability is
subtype My_Characters is
Character range 'a' .. 'z';
package My_Random_Character_Package is
new Ada.Numerics.Discrete_Random(My_Characters);
use My_Random_Character_Package;
Gen_1 : My_Random_Character_Package.Generator;
procedure My_Character_Program(First_Character, Second_Character : in Character) is
begin
Put(First_Character);
Put(" ");
Put(Second_Character);
New_Line;
Put("All characters between ");
Put(First_Character);
Put(" and ");
Put(Second_Character);
Put(":");
for C in Character range First_Character .. Second_Character loop
Put(" ");
Put(A);
end loop;
end My_Character_Program;
procedure Part_2 is
First_Character, Second_Character : Character;
begin
Put_Line("PART 2:");
Put_Line("Two random characters from a to z will now be generated.");
Put("Random characters: ");
First_Character := Random(Gen_1);
Second_Character := Random(Gen_1);
if First_Character > Second_Character then
My_Character_Program(Second_Character, First_Character);
else
My_Character_Program(First_Character, Second_Character);
end if;
end Part_2;
begin
-- Reset(Gen_1);
Part_2;
New_Line(2);
end Probability;
The following program will pick two random letters between A and Z and then it will type out all the letters thats between them. So for instance if it randomly generates the letters
d and g
it will type out
d e f g
But I need your asstistance. Even if my program works I don't think its executed that well, especially the part 2. Is there not a way where I can put a part of my "Part 2 procedure" in my "My character program procedure"? As you can see I swaped the first and second character. Can I not do that in another way?
I appreciate any help that I could get.
Look at your 'toolbox' -- Ada provides exactly what you want, in the form of subtype and the Succ/Pred attributes, which you already used.
procedure My_Character_Program(First, Second : in Character) is
Subtype Middle is Character range
Character'Succ(First)..Character'Pred(Second);
begin
Put_Line( First & ' ' & Second );
Put("All characters between " & First & " and " & Second & ':');
for C in Middle loop
Put(' ' & C);
end loop;
Put_Line( "." );
end My_Character_Program;
As for Part_2, allow me to suggest that a much better method is to use inline declare-blocks and attributes/renaming.
--...
First_Character := Random(Gen_1);
Second_Character := Random(Gen_1);
Declare
First : Character renames Character'Min(First_Character,Second_Character);
Second : Character renames Character'Max(First_Character,Second_Character);
Begin
My_Character_Program(First, Second);
End;
I’d be inclined to try a bit of recursion (and reduce the number of calls to Put - sorry, style issue, not your question I know):
procedure My_Character_Program
(First_Character, Second_Character : in My_Characters)
is
begin
if First_Character > Second_Character then
My_Character_Program (Second_Character, First_Character);
else
begin
Put_Line (First_Character & " " & Second_Character);
Put("All characters between "
& First_Character
& " and "
& Second_Character
& ":");
for C in My_Characters range First_Character .. Second_Character
loop
Put(" " & C);
end loop;
New_Line;
end;
end if;
end My_Character_Program;
An alternate approach is:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Main is
subtype letters is Character range 'a' .. 'z';
package rand_letter is new Ada.Numerics.Discrete_Random (letters);
use rand_letter;
seed : Generator;
procedure print_range (First : letters; Last : letters) is
begin
for C in Character'Min (First, Last) .. Character'Max (First, Last) loop
Put (C);
end loop;
New_Line;
end print_range;
begin
Reset (seed);
for I in 1 .. 7 loop
print_range (Random (seed), Random (seed));
end loop;
end Main;

Ada - Skipping Whitespace using look_ahead

I have a procedure, that in theory, should be skipping whitespace using a look_ahead loop. Problem is, it's not working, if there's any whitespace in the input file, it is adding it to the array of records. I think my logic is correct, but could use another pair of eyes to let me know what I'm missing, and why it's not working.
PROCEDURE Read(Calc: OUT Calculation) IS
EOL: Boolean;
C: Character;
I: Integer := 1;
BEGIN
LOOP
LOOP
Look_Ahead(C, EOL);
EXIT WHEN EOL or C /= ' ';
Get(C);
END LOOP;
EXIT WHEN ADA.Text_IO.END_OF_FILE;
Look_Ahead(C, EOL);
IF Is_Digit(C) THEN
Calc.Element(I).Kind := Number;
Get(Calc.Element(I).Int_Value);
ELSE
Calc.Element(I).Kind := Symbol;
Get(Calc.Element(I).Char_Value);
END IF;
Calc.Len := Calc.Len+1;
IF Calc.Element(I).Char_Value = '=' THEN
EXIT;
END IF;
I := I+1;
END LOOP;
END Read;
EDIT: If any of the other procedures, the code for the record etc is needed for an answer, let me know and I will post it.
For Ada.Text_IO.Look_Ahead, ARM A.10.7(8) says
Sets End_Of_Line to True if at end of line, including if at end of page or at end of file; in each of these cases the value of Item is not specified. Otherwise, End_Of_Line is set to False and Item is set to the next character (without consuming it) from the file.
(my emphasis) and I think the "without consuming it" is key. Once Look_Ahead has found an interesting character, you need to call Get to retrieve that character.
I hacked this little demo together: I left end-of-file to exception handling, and I called Skip_Line once end-of-line’s been seen because just Get wasn’t right (sorry not to be more precise!).
with Ada.Text_IO;
with Ada.IO_Exceptions;
procedure Justiciar is
procedure Read is
Eol: Boolean;
C: Character;
begin
-- Instead of useful processing, echo the input to the output
-- replacing spaces with periods.
Outer:
loop
Inner:
loop
Ada.Text_IO.Look_Ahead (C, Eol);
exit Outer when Eol; -- C is undefined
exit Inner when C /= ' ';
Ada.Text_IO.Get (C); -- consume the space
Ada.Text_IO.Put ('.'); -- instead of the space for visibility
end loop Inner;
Ada.Text_IO.Get (C); -- consume the character which isnt a space
Ada.Text_IO.Put (C); -- print it (or other processing!)
end loop Outer;
Ada.Text_IO.Skip_Line; -- consume the newline
Ada.Text_IO.New_Line; -- clear for next call
end Read;
begin
loop
Ada.Text_IO.Put ("reading: ");
Read;
end loop;
exception
when Ada.IO_Exceptions.End_Error =>
null;
end Justiciar;
Usually it's better to read an entire line and parse it than to try to parse character by character. The latter is usually more complex, harder to understand, and more error prone. So I'd suggest something like
function De_Space (Source : String) return String is
Line : Unbounded_String := To_Unbounded_String (Source);
begin -- De_Space
Remove : for I in reverse 1 .. Length (Line) loop
if Element (Line, I) = ' ' then
Delete (Source => Line, From => I, Through => I);
end if;
end loop Remove;
return To_String (Line);
end De_Space;
Line : constant String := De_Space (Get_Line);
You can then loop over Line'range and parse it. Since I'm not clear if
Get(C);
Get(Calc.Element(I).Int_Value);
Get(Calc.Element(I).Char_Value);
represent 1, 2, or 3 different procedures, I can't really help with that part.

Convert if statement to case of in pascal?

Im using pascal, can u convert this code statement to case of ? In pascal ?
This my program on pascal, if statement to case of.
Thankyou very much
TYPE
MHS = record
nama1,nama2:string;
ipk1,ipk2:longint;
nim1,nim2:integer;
end;
var
DataMhs : MHS;
Begin
clrscr;
write('Masukan Nama Mahasiswa 1 : ');
readln(DataMhs.nama1);
write('Masukan NIM Mahasiswa 1 : ');
readln(DataMhs.nim1);
write('Masukan IPK Mahasiswa 1 : ');
readln(DataMhs.ipk1);
write('Masukan Nama Mahasiswa 2 : ');
readln(DataMhs.nama2);
write('Masukan NIM Mahasiswa 2 : ');
readln(DataMhs.nim2);
write('Masukan IPK Mahasiswa 2 : ');
readln(DataMhs.ipk2);
if DataMhs.ipk1 > DataMhs.ipk2 then
write('IPK ',DataMhs.nama1,'Lebih besar')
else if DataMhs.ipk2 > DataMhs.ipk1 then
write('IPK ',DataMhs.nama2,'Lebih besar')
else
write('IPK ',DataMhs.nama1,' dengan ',DataMhs.ipk2,' SAMA');
readln;
end.
I dont know how to convert it, please help. Haha
If you want to make you code better looking, then you can use that -->
with DataMhs do
begin
if ipk1 > ipk2 then write('IPK ',DataMhs.nama1,'Lebih besar');
else if ipk1 < ipk2 then write('IPK ',DataMhs.nama2,'Lebih besar');
else write('IPK ',DataMhs.nama1,' dengan ',DataMhs.ipk2,' SAMA');
end;
But I do not think that the case
is useful for that. Because case is used for known values such as:
case a of
1: Writeln(' Some code here') ;
2: Writeln(' Some code here') ;
3: Writeln(' Some code here') ;
4: Writeln(' Some code here') ;
else Writeln(' That is used for other values. ');
end;
Case cannot be used for that kind of problem.
I suspect that what you have in mind might be something like the following:
type
TCompareResult = (cmpLeftGreater, cmpRightGreater, cmpEqual);
case CompareInts(DataMhs.ipk1, DataMhs.ipk2) of
cmpLeftGreater:
write('IPK ', DataMhs.nama1, 'Lebih besar');
cmpRightGreater:
write('IPK ', DataMhs.nama2, 'Lebih besar');
else {cmpEqual}
write('IPK ', DataMhs.nama1, ' dengan ', DataMhs.ipk2, ' SAMA');
end;
However, you still need to implement this CompareInts function, and it will still need to use the same conditional structure you already have in your original code:
function CompareInts(left, right: Integer): TCompareResult;
begin
if left > right then
Result := cmpLeftGreater
else if right > left then
Result := cmpRightGreater
else
Result := cmpEqual;
end;
Thus, the function doesn't really gain you much.

What's wrong with this Pascal syntax?

I can't understand what's going on here. Can you give me a hand? This is the problematic code:
While not EOF(Archi) do begin
index:= index + 1;
Read(Archi, Alumno[index]);
Promes[index] := (Alumno[index].nota1 + Alumno[index].nota2) / 2;
if Promes[index] >= 6 then begin
alguPromo := true;
PromosIndex := PromosIndex + 1;
Promos[PromosIndex]:= Alumno[index];
end;
else begin
if Promes[index] > 4 then cantiRecu:= cantiRecu + 1;
else begin
LibresIndex += 1;
Libres[LibresIndex] := Alumno[index];
end;
end;
end;
The compiler marks error in the line 10 of this code (else begin). The error is:
Fatal: Syntax error, ; expected but ELSE found.
If someone wants to tray compile here is the entire code: http://pastebin.com/dRg1Lguu
Note that in Pascal the semicolon is a separator, not a terminator. Sometimes this doesn't matter, but in some cases it does, particularly before an else. Your code should be:
while not EOF(Archi) do
begin
index:= index + 1;
Read(Archi, Alumno[index]);
Promes[index] := (Alumno[index].nota1 + Alumno[index].nota2) / 2;
if Promes[index] >= 6 then
begin
alguPromo := true;
PromosIndex := PromosIndex + 1;
Promos[PromosIndex] := Alumno[index]
end
else
begin
if Promes[index] > 4 then
cantiRecu:= cantiRecu + 1
else
begin
LibresIndex := LibresIndex + 1;
Libres[LibresIndex] := Alumno[index]
end
end
end
Note that I have re-formatted the code into a more conventional style which helps to make the program logic more easily understood and which also makes it more obvious where the semicolons are needed and where they are not.
Looks like problem in += operator

Resources