program Assignment6(input, output);
Var
   file1 : text;
   c     : char;
   error : boolean;
   num1  :  integer;

function convert(c: char): integer;
begin
   convert := ord(c) - ord('0');
end; { convert }

function find_digits(var c : char): integer;

Var
   num : integer;

begin
   num := 0;
   while (ord(c) >= ord('0')) and (ord(c) <= ord('9')) do
begin
   num := num * 10 + (ord(c) - ord('0'));
   read(file1, c);
end;
end; { find_digits }

procedure ignorespaces;
begin
   while c = ' ' do
      read(file1, c);
end; { ignore_spaces }




BEGIN

   assign(file1, 'input.txt');
   reset(file1);
   read(file1, c);
   error := false;
   ignorespaces;
   If ((ord(c) >= ord('0')) and (ord(c) <= ord('9'))) then
begin
   find_digits;
   num1 := find_digits(c);


end;


end.

ok it makes more sense having it an function. Did I write the function find_digits right? Is the num suppose to be declared like that? Would I need to change anything in the main program now? Getting these errors c6.p: In function `Find_digits':

c6.p:25: warning: return value of function not assigned
c6.p: In main program:
c6.p:45: too few arguments to function `Find_digits'
c6.p:45: warning: function call as a statement - value is ignored

EDIT: Ok i got most of the errors down, last one is giving me a hard time.
warning: return value of function not assigned

Yes, it looks good, except that you aren't returning the value of num.

Notice in "convert" you return the value ord(c) - ord('0') by "assigning it" to the function name: convert := ord(c) - ord('0') In any BP dialect, you can also say: result := ord(c) - ord('0') The "find_digits" function goes through all the trouble of calculating "num", but it fails to say: find_digits := num at the end...

You forgot to remove the "find_digits" all by itself right after the "begin". The next one is correct.

Good job!

[EDIT] Oh yeah, the "ignorespaces" needs to account for the next character the same way:

procedure ignorespaces( var c: char );
  begin
  while c = ' ' do
    read( file1, c )
  end;

All your procedures and functions will have the same issue: they'll have to have a var c: char in the parameter list.

Hope this helps.

OK, sorry for the double post.

The reason it hasn't complained about "c" is that it is a global variable, which I am trying to get you to avoid using. The same is true of "file1". In all your procedures and functions, you could get rid of the "var c: char" parameter and your program would work fine.

What I would like to see, though, is something like this:

program foo;

procedure ignorespaces( var f: textFile; var c: char );
  begin
  while c = ' ' do read( f, c )
  end;

{ The following variables are 'local' to the main program's block. }
var
  my_file: textFile;
  my_char: char;

begin
  ...
  ignorespaces( my_file, my_char );
  ...
end.

This makes your code more modular and more understandable. The "ignorespaces" function only cares about information given to it. You could use it on any file you want --even multiple files at the same time.

var
  my_file:      textFile;
  my_char:      char;
  another_file: textFile;
  another_char: char;

begin
  ...
  ignorespaces( my_file, my_char );
  ignorespaces( another_file, another_char );
  ...
end.

Hope this helps.

AHHHHHHH i see now. Changing this stuff gives me a new error

program Assignment6(input, output);
Var
   file1 : text;
   c     : char;
   error : boolean;
   num1  :  integer;

function convert(c: char): integer;
begin
   convert := ord(c) - ord('0');
end; { convert }

function find_digits(var c : char): integer;

Var
   num : integer;

begin
   num := 0;
   while (ord(c) >= ord('0')) and (ord(c) <= ord('9')) do
begin
   num := num * 10 + (ord(c) - ord('0'));
   read(file1, c);
   find_digits := num;
end;
end; { find_digits }

procedure ignorespaces(var c : char);
begin
   while c = ' ' do
      read(file1, c);
end; { ignore_spaces }




BEGIN

   assign(file1, 'input.txt');
   reset(file1);
   read(file1, c);
   error := false;
   [B]ignorespaces;[/B]
   If ((ord(c) >= ord('0')) and (ord(c) <= ord('9'))) then
begin
   num1 := find_digits(c);


end;


end.

thanks for all the help. Everything is making sense now. I get an error on the part I bolded in the code.
too few arguments to function `Ignorespaces'

If I understand correctly, this is what I have

program Assignment6(input, output);
Var
   error   : boolean;
   num1    : integer;
   my_file : text;
   my_char : char;

function convert(c: char): integer;
begin
   convert := ord(c) - ord('0');
end; { convert }

function find_digits(var c : char): integer;

Var
   num : integer;

begin
   num := 0;
   while (ord(c) >= ord('0')) and (ord(c) <= ord('9')) do
begin
   num := num * 10 + (ord(c) - ord('0'));
   read(my_file, my_char);
   find_digits := num;
end;
end; { find_digits }

procedure ignorespaces(var f : text; var c : char);
begin
   while c = ' ' do
      read(f, c);
end; { ignore_spaces }




BEGIN

   assign(my_file, 'input.txt');
   reset(my_file);
   read(my_file, my_char);
   error := false;
   ignorespaces(my_file, my_char);
   If ((ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9'))) then
begin
   num1 := find_digits(my_char);


end;


end.

It now compiles if I add a writeln(num1); after 'num1 := find_digits(my_char);" I get an output as 5 (that is the first digit in the equation)

Beautiful!

Now that you have the 5, what are you going to do with it?

[EDIT] Wait! Er... Your find_digits is using the global variables 'my_file' and 'my_char'. To help you out, I would like you to take that entire

Var
   error   : boolean;
   num1    : integer;
   my_file : text;
   my_char : char;

block and move it so that it is immediately before the BEGIN .

Your program will then not compile. See if you can fix it so that it does (without putting the var block back at the top).

program Assignment6(input, output);


function convert(c: char): integer;
begin
   convert := ord(c) - ord('0');
end; { convert }

function find_digits(var my_char : char; var  my_file : text): integer;

Var
   num : integer;

begin
   num := 0;
   while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
   num := num * 10 + (ord(my_char) - ord('0'));
   read(my_file, my_char);
   find_digits := num;
end;
end; { find_digits }

procedure ignorespaces(var f : text; var c : char);
begin
   while c = ' ' do
      read(f, c);
end; { ignore_spaces }



Var
   error   : boolean;
   num1    : integer;
   my_file : text;
   my_char :  char;


BEGIN

   assign(my_file, 'input.txt');
   reset(my_file);
   read(my_file, my_char);
   error := false;
   ignorespaces(my_file, my_char);
   If ((ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9'))) then
begin
   num1 := find_digits(my_char, my_file);

end;
end.

Is this correct? Now, would A loop allow me to get all the numbers from the equation? If I put the loop right after the num1 := find_digits(my_char, my_file);

> Is this correct?
Perfect.

Keep in mind, you don't have to use the same names in your function as you do for the globals. Your function could be:

function find_digits(var c : char; var  f : text): integer;
  Var
    num : integer;
  begin
    num := 0;
    while c in ['0'..'9'] do
      begin
      num := num * 10 + (ord(c) - ord('0'));
      read(f,c);
      end;
    find_digits := num;
  end; { find_digits }

(I made a couple of other changes too, just to show you how you can think of some things...)

> Now, would A loop allow me to get all the numbers from the equation? If I put the loop right after the num1 := find_digits(my_char, my_file);

You are going to have to think about this one with the construction paper and crayons a little bit. What is the next character you read going to look like? (You already know it is not a digit, otherwise find_digits would have read it. So when find_digits finishes and returns a number, my_char is hopefully going to be one of '+' or '-' or '*' or '(' or something like that. If not it is invalid and you can complain about the equation.) Here again is a list of valid equations:

1+2+3
-9+10
12*-2
5*(2+3)
(2*(1+3))-1

And some invalid ones:

3,7
+
We're #1!

Hope this helps.

> Is this correct?
Perfect.

Keep in mind, you don't have to use the same names in your function as you do for the globals. Your function could be:

function find_digits(var c : char; var  f : text): integer;
  Var
    num : integer;
  begin
    num := 0;
    while c in ['0'..'9'] do
      begin
      num := num * 10 + (ord(c) - ord('0'));
      read(f,c);
      end;
    find_digits := num;
  end; { find_digits }

(I made a couple of other changes too, just to show you how you can think of some things...)

> Now, would A loop allow me to get all the numbers from the equation? If I put the loop right after the num1 := find_digits(my_char, my_file);

You are going to have to think about this one with the construction paper and crayons a little bit. What is the next character you read going to look like? (You already know it is not a digit, otherwise find_digits would have read it. So when find_digits finishes and returns a number, my_char is hopefully going to be one of '+' or '-' or '*' or '(' or something like that. If not it is invalid and you can complain about the equation.) Here again is a list of valid equations:

And some invalid ones:


Hope this helps.

Ill think about it, I also HAVE to use arrays in this assignment.

program Assignment6(input, output);


function convert(c: char): integer;
begin
   convert := ord(c) - ord('0');
end; { convert }

function find_digits(var my_char : char; var  my_file : text): integer;

Var
   num : integer;

begin
   num := 0;
   while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
   num := num * 10 + (ord(my_char) - ord('0'));
   read(my_file, my_char);
   find_digits := num;
end;
end; { find_digits }

procedure ignorespaces(var f : text; var c : char);
begin
   while c = ' ' do
      read(f, c);
end; { ignore_spaces }



Var
   error       : boolean;
   num1, num2  : integer;
   my_file     : text;
   my_char     : char;
   temp_result : real;
   oper        : char;

BEGIN

   assign(my_file, 'input.txt');
   reset(my_file);
   read(my_file, my_char);
   error := false;
   ignorespaces(my_file, my_char);

   num1 := find_digits(my_char, my_file);
   [B]temp_result := num1;
   oper := my_char;

   If oper = '+' then
      begin
         temp_result := temp_result + num2;
         writeln(temp_result);
      end;
  If oper = '-' then
      begin
         temp_result := temp_result - num2;
         writeln(temp_result);
      end;

      If oper = '*' then
      begin
         temp_result := temp_result * num2;
         writeln(temp_result);
      end;

      If oper = '/' then
      begin
         temp_result := temp_result / num2;
         writeln(temp_result);
      end;[/B]



end.

I am pretty stumped now, that is all I could think of (look at code). Now, I am having troubles figuring out how to read the second number "num2". The writeln are just in there for testing.

Rather than a bunch of "if foo = x ... " statements, use a "case foo of" statement:

case oper of
  '+': begin
       ...
       end;
  '-': begin
       ...
       end;
  end;

You've already got a function that will read a number. (You used it to get num1.) Use it to get num2.

While you are moving along quite logically... your current line of thought is taking you toward that recursive descent algorithm that ExplainThat mentioned in joygqy's thread... there are no arrays in sight. If you are not to use records I'm at a loss as to how your professor expects you to use an array. You should take what you've got so far and go see him and ask how he wants you to put your equation into an array.

(Frankly, I think the assignment has a few points that are a little over the top. While simple, it is not trivial, and it is definitely not a beginner-level thing to properly handle mathematical expressions...)

Still having alittle troubles getting that the second digits. I came up with this

while (my_char <> '=') and (not eoln(my_file)) do
   begin
      ignorespaces(my_file, my_char);
      num2 := find_digits(my_char, my_file);
      read(my_file, my_char);
      write(num2);
   end;

This gives me all the digits that I have in my file. My file consists of 2 equations:
5+4-3*2=
3+4/2*3=

This while loop gives me the output of 54323423

Ok, I messing around some more with my code and made it to give an output of 5 4 3 2 (where "5" is num1, and "4 3 2" are num2). I was trying to think of a way to put the numbers in an array but nothing worked.

The logic I am trying to use to solve this problem is as follows:
1. Num1 would be a "temporary result"
2. Read the next number, perform the operation needed. save this new number as "temporary result"
3. and repeat this

The problem is I don't know how to make "num2" be a single number that is the next number in my equation. So, I would want num2 to be "4" and so on, until the problem is solved.

You are on the cusp of getting it.

Num2 can never be more than one number at once. It can be different numbers at different times... it is a different number each time through the loop (you get a new num2, print it, then go through the loop again to repeat).

So your logic steps are good and correct. The problem is there is no array anywhere in there. Hence why you need to go bug your prof.

I am lost trying to get num2 to equal the second digit, then the next time the loop is ran it equals the third digit?

I don't understand why you are confused.
1. You use find_digits to read num1 (the first number).
2. You read a character (one of '+' or '-' or something).
3. You use find_digits to read num2 (the second number).
4. You read a character (one of '+' or '-' or something).
5. You use find_digits to read num2 (the third number).
6. You read a character (one of '+' or '-' or something).
7. You use find_digits to read num2 (the fourth number).

Make sense?

Yea it makes sense, except whenever I try to find num2 (and all the digits after it) I just keep getting num1

case oper of
         '+' : begin
            num2 := find_digits(my_char, my_file);
            temp_result := num1 + num2;
         end;
         '-' : begin
            num2 := find_digits(my_char, my_file);
            temp_result := num1 - num2;
         end;
         '*' : begin
            num2 := find_digits(my_char, my_file);
            temp_result := num1 * num2;
         end;
         '/' : begin
            num2 := find_digits(my_char, my_file);
            temp_result := num1 div num2;
         end;
       end; { case }

Now, the problem I am having trouble with is the trying to keep reading the next number. Since my equations are
5+4-3*2=
3+4/2*3=
This case loop will give me output of 9 8 7 (not sure where the 8 is coming from). There is still something wrong, the loop is read both lines at once.

Well, you know that the loop is reading the numbers correctly (because you before tested it by just reading and printing the numbers, and they printed the correct numbers).

But now that you are doing something to the numbers something is wrong.

May I suggest that num1 and temp_result should be the same variable?

Well, you know that the loop is reading the numbers correctly (because you before tested it by just reading and printing the numbers, and they printed the correct numbers).

But now that you are doing something to the numbers something is wrong.

May I suggest that num1 and temp_result should be the same variable?

Not sure what you mean here, I have temp_result := num1; ?

I am having enough trouble as it is trying to get this too work. And I also need to make my program do operator presedence and evaluate brackets first. And somehow tie arrays into it all. Here is an example of how arrays are used in this assignment.

procedure analyze(a : integer; b : integer);

begin
   var oper               : char;
      num1, num2, i, j, k : integer

   For i := (a+1) to (b-1) do
   begin
      If arr[i] := ('*' or '/') then
      begin
         num2 := 0;
         j := i + 1;

         repeat
            if (ord(arr[i]) >= ord('0')) and (ord(arr[i]) <= ord('9')) then
            begin
               num2 := num2 * 10 + ord(array[i]) - ord('0');
            end;
            j := j + 1;

         until (ord(arr[i]) < ord('0')) or (ord(arr[i] > ord('9'))

 end;

Even though this code doesn't really accomplish much, it is an example of what I am suppose to do.

Yea man, I think I need to start all over using arrays :'(. All that work for nothing (i think).

So this is what I am thinking:

1. read from input file
2. Put the equation from input file into an array
3. use a procedure to get rid of spaces in the equation (if any)
4. another procedure to evaluate brackets
5. Evaluate the equation

What do you think?


This assignment seems way to hard for a beginner :(

It is hard for a beginner, but not quite "way too hard".

Let me think a bit and post back later. My brain hurts and I'm tired of going around in circles with you.

Some quick things first:
1. Your last thoughts seem like a good plan.
2. Please get out some paper and draw how to accomplish each thing.
3. Please go talk to your prof.
4. See my post #7 for some big help. Just ignore the stuff about using records. Everything else applies.
5. temp_result := num1 causes them to both have the same value, which is not what I said. You don't need two variables with the same value. You need one variable that does what you are currently doing with two.

I'll post again in a day or after I've gotten some sleep.:yawn:

OK, I've had time to think it over.

Your post #50 is a good plan. You haven't "wasted" any time. You've learned a good deal and what you have learned directly applies to your assignment.

1. read from input file
2. Put the equation from input file into an array

These things can be done together. You have already developed a loop that gets numbers and operators from a file. The only thing you haven't done is considered the possibility that two operators may be next to each other (legally). My post #38 gives you both valid and invalid examples.

As a hint, consider what would happen if you called "find_digits" when c was not a digit. Your routines to read operators and skip spaces and the like should do the same thing.

3. use a procedure to get rid of spaces in the equation (if any)

Don't bother. Spaces can be filtered out when reading from file into an array.

4. another procedure to evaluate brackets

Brilliant! I suggest that the procedure that evaluates brackets be the same procedure that evaluates an equation. procedure evaluate( equ: tEquationArray; len: cardinal; start, stop: cardinal ); This procedure takes an equation array, its length, and what part of the array is to be evaluated. So, given an equation like 0 1 2 3 4 5 6 5 * ( 2 + 3 ) you can first call with: evaluate( ..., 7, 0, 6 ); Since the equation has a sub-equation (due to parentheses), your procedure can find the sub-equation and evaluate it with: evaluate( ..., 7, 2, 6 ) (which includes the parentheses to remove)
or evaluate( ..., 7, 3, 5 ) (which excludes the parentheses to remove).
You must decide where you want to remove parentheses, in recursion or after recursion.

It might be handy to have a procedure which simply finds the indices of the leftmost, outermost pair of matching parentheses.

5. Evaluate the equation

Yes. This should be done as part of the "equation" routine, but after the parentheses are handled. What this means is all you need to worry about is numbers and normal operators like +, -, *, etc. See my post #7 for more.


Don't get discouraged. This is a big assignment (and I think, a poorly planned one...). But you can do it if you take the time to think, and keep separate things separate. When reading numbers, only worry about reading numbers. When reading operators, only worry about reading operators. When removing elements in the equation array and replacing them with a single element (a number), worry only about modifying the array. Etc.

Hope this helps.

Brilliant! I suggest that the procedure that evaluates brackets be the same procedure that evaluates an equation.
procedure evaluate( equ: tEquationArray; len: cardinal; start, stop: cardinal );
This procedure takes an equation array, its length, and what part of the array is to be evaluated. So, given an equation like
0 1 2 3 4 5 6
5 * ( 2 + 3 )
you can first call with:
evaluate( ..., 7, 0, 6 );
Since the equation has a sub-equation (due to parentheses), your procedure can find the sub-equation and evaluate it with:
evaluate( ..., 7, 2, 6 ) (which includes the parentheses to remove)
or
evaluate( ..., 7, 3, 5 ) (which excludes the parentheses to remove).
You must decide where you want to remove parentheses, in recursion or after recursion.

It might be handy to have a procedure which simply finds the indices of the leftmost, outermost pair of matching parentheses.

I like the idea of that procedure, but I am not sure how to exactly write it up. When you declared equ : tEquationArray , do I need to make a type for this? Do I need to change the way I am reading the file for my entire program? Instead of reading a character do I read as a string and put it into the array?

How did your professor say you should define your array?

HMmm, it never said we had to. Another thing, the equation in the input file is assumed to be valid. So I don't have to worry about all the errors.

Hold on. The entire length of this thread you've maintained that your professor wants you to use an array.

"Every time an intermediate result is calculated the corresponding components of that calculation are removed from the array(s) and replaced with the correct answer".

Did he or did he not? Which is it?

Hold on. The entire length of this thread you've maintained that your professor wants you to use an array.

Every time an intermediate result is calculated the corresponding components of that calculation are removed from the array and replaced with the correct answer.

Did he or did he not? Which is it?

Yes that is correct, " Every time an intermediate result is calculated the corresponding components of that calculation are removed from the array and replaced with the correct answer." is something is we need to do.

4 + 2 * 5 +2 = 4 + 10 + 2

Alright. Since your equation is to be stored in an array, and you are not permitted to store it in an array of records, then how are you supposed to store it? What does he want you to use for each element of the array?

" Your program MUST use an array as the main storage medium for the equation " . So, I guess you need to use an array for the main storage but doesn't have to use an array all the time?

That's too vague. Is it an array of integers? Is it an array of strings? Is it an array of reals? Chars? Enumerations? Sets?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.