Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Buchungsprogramm addiert nicht


chrizzly123 - Sa 08.01.11 16:06
Titel: Buchungsprogramm addiert nicht
Hallo,
ich habe ein problem mit Delphi 7. WIr sollen bis Montag ein "Protfolio" für unseren Informatik-Lehrer erstallen (wird benotet). Das Problem ist das ich in Informatik nicht der Hellste bin und ein Programm von mir nicht funktioniert -.-
Könntet ihr mir eventuel helfen? Wäre sehr nett von euch!
Hier der Quellcode:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
program Buchungsprogramm;  (*Programm nimmt Rechnung entgegen,addiert MWST und gibt die Summen mit und ohne MWST sowie den MWST-Betrag aus!*)
{$APPTYPE CONSOLE}
uses
  SysUtils;
type
  TBuchung=array of real;
var
  Buchung : TBuchung;
  max : integer ;
  summ, dumm, lumm : real;
  f:char;
  procedure Eingabe(var einbuchung:TBuchung; var sax:integer);
   begin
   max:=1;
    repeat
    Write(max,'.Betrag: ');
    setLength(einBuchung,max);
    ReadLn(einbuchung[max]);
    inc(max);
    writeLn('Weiter? j/n');
    readLn(f);
    until f='n';
   end;
  procedure Addition(var adbuchung : TBuchung; var max : integer; var sum : real);
  var o:integer;

   begin
   writeLn(max);
   sum:=0;
   for o:=1 to max do
   writeLn(Adbuchung[o]);
   end;
  procedure Steuer(var summa,fumma,summo:real);
   begin
   fumma:=summa*19/100;
   summo:= summa+fumma;
   end;
  procedure Ausgabe(somma,fomma,fommo:real);
   begin
   writeLn(' Rechnung:');
   writeLn('  Summe:            ',somma:6:2);
   writeLn('  MWS:             +',fomma:6:2);
   writeLn('                   ________');
   WriteLn('  Rechnungsbetrag:  ',fommo:6:2);
   end;
begin // Hauptprogramm
  Eingabe(Buchung, max);
  Addition(buchung , max , summ);
  Steuer(summ, dumm, lumm);
  Ausgabe(summ, dumm, lumm);
  readLn;
end.




Das Programm soll beliebig viele Zahlen lese, addieren, 19% MWST drauf rechnen und dann ausgeben (für die Kasse).
Bei mir nimmt es jedoch nur die letzte Zahl und addiert nicht alle Zahlen. Wisst ihr woran das liegt?


Mit freundlichen Grüßen
Chrizzly123

Moderiert von user profile iconMartok: Delphi-Tags gesetzt


bummi - Sa 08.01.11 16:54


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TBuchung = array of Double;

var
  Buchung: TBuchung;
  max: integer;
  summ, mwst,incMWST: Double;
  f: char;

procedure Eingabe;
begin
  max := 0;
  repeat
    Write(max + 1'.Betrag: ');
    setLength(Buchung, max + 1);
    ReadLn(Buchung[max]);
    inc(max);
    writeLn('Weiter? j/n');
    ReadLn(f);
  until f = 'n';
end;

procedure Addition;
var
  i: integer;

begin
  writeLn(max);
  summ := 0;
  for i := 0 to max do
    begin
    summ := summ + Buchung[i];
    writeLn('Pos ' + IntToStr(i + 1)+'.', Buchung[i]:6:2);
    end;
end;

procedure Steuer;
begin
  mwst := summ * 19 / 100;
  incMWST := summ + Mwst;
end;

procedure Ausgabe;
begin
  writeLn(' Rechnung:');
  writeLn(' Summe: ', summ:6:2);
  writeLn(' MWS: +', MWST:6:2);
  writeLn(' ________');
  writeLn(' Rechnungsbetrag: ', IncMWst:6:2);
end;

begin // Hauptprogramm
  Eingabe;
  Addition;
  Steuer;
  Ausgabe;
  ReadLn;

end.


Tranx - Sa 08.01.11 17:01

Schreibe mal Dein Programm in Delphi-Tags, damit man es lesen kann:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
uses
  SysUtils;

type
  TBuchung = array of real;

var
  Buchung : TBuchung;
  max : integer ;
  summ, dumm, lumm : real;
  f:char;

procedure Eingabe(var einbuchung: TBuchung; var max: integer); // hier muss wohl max statt sax stehen
begin
  max:=1
  repeat
    Write(max,'.Betrag: ');
    setLength(einBuchung,max);
    ReadLn(einbuchung[max]);
    inc(max);
    writeLn('Weiter? j/n');
    readLn(f);
  until f='n';
end;

procedure Addition(var adbuchung : TBuchung; var max : integer; var sum : real);
var 
  o:integer;
begin
  writeLn(max);
  sum:=0;
  for o:=1 to max do
    writeLn(Adbuchung[o]);
end;

procedure Steuer(var summa,fumma,summo:real);
begin
  fumma:=summa*19/100;
  summo:= summa+fumma;
end;

procedure Ausgabe(somma,fomma,fommo:real);
begin
  writeLn(' Rechnung:');
  writeLn(' Summe: ',somma:6:2);
  writeLn(' MWS: +',fomma:6:2);
  writeLn(' ________');
  WriteLn(' Rechnungsbetrag: ',fommo:6:2);
end;

begin // Hauptprogramm
  Eingabe(Buchung, max);
  Addition(buchung , max , summ);
  Steuer(summ, dumm, lumm);
  Ausgabe(summ, dumm, lumm);
  readLn;
end.


jaenicke - Sa 08.01.11 17:15

du hast da einen Indexfehler drin...

Delphi-Quelltext
1:
2:
setLength(einBuchung,max);
ReadLn(einbuchung[max - 1]);


Tranx - Sa 08.01.11 17:34

Hier mein Vorschlag:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
program Buchungen;
{$APPTYPE CONSOLE}
uses
  SysUtils;

var
  Summe, Steuer : real;

function Eingabe : real;
var
  s:string;
  Betrag : real;
  Nummer : integer;
begin
  Nummer := 1;
  repeat
    Write(Nummer,'.Betrag (Ende mit -1): ');
    Readln(s);
    try
      Betrag := StrToFloat(s);
      if Betrag<>-1.0 then
      begin
        Summe := Summe + Betrag;
        inc(Nummer);
      end;
    except
      WriteLn('Fehleingabe, keine Zahl! Weiter mit beliebiger Taste');
      ReadLn;
    end;
  until Betrag=-1.0;
  Result := Summe;
end;


function MWSteuer(const Summe : real) : real;
begin
  Result := 0.19*Summe;
end;

procedure Ausgabe(Summe, Steuer :real);
begin
  WriteLn;
  WriteLn(' Rechnung:');
  WriteLn(' Summe:           ',Summe:6:2);
  WriteLn(' MWS: +           ',Steuer:6:2);
  WriteLn(' ___________________________________');
  WriteLn(' Rechnungsbetrag: ',Summe+Steuer:6:2);
end;

begin // Hauptprogramm
  Summe := Eingabe;
  Steuer := MWSteuer(Summe);
  Ausgabe(Summe, Steuer);
  readLn;
end.



Was habe ich geändert?

1. weniger Globalvariable
2. Kein varianter Array, da Du doch sowieso nicht auf die einzelnen Beträge zugreifst. Bei Deiner Eingabe werden nämlich schon eingegebene Beträge durch Setlength gelöscht.
3. Summenbildung schon in der Eingaberoutine
4. Funktionen statt Prozeduren, zur Übergabe von Summe und Steuer.
5. Keine Parameter für Eingabe, weil nicht notwendig
6. Überprüfung, ob eine Eingabe auch eine Zahl ist (try .. except)

Jänicke, Entschuldige, den Indexfehler habe ich nicht gesehen. Falls er doch die Beträge nutzen will, was bei dem Programm so nicht der Fall ist, muss er eben es so schreiben, wie Du es verbessert hast.


elundril - Sa 08.01.11 17:52

1. Real verwendet man afaik nicht mehr, sondern double.
2. Das Try-Except-Konzept ist mMn falsch und gehört durch ein tryStrToFloat ersetzt (exceptions vermeiden statt abfangen)
3. Repeat-until wegen der geschwindigkeit zu while machen (ist aber zweitrangig)
4. Nicht auf -1.0 überprüfen sondern mit samevalue(a,b) arbeiten


aber sonst hast du brav seine Hausübungen gemacht. ;)

lg elundril


Tranx - Sa 08.01.11 17:57

Alternativ wäre ja noch:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
program TestBuchungen; (*Programm nimmt Rechnung entgegen,addiert MWST und gibt die Summen mit und ohne MWST sowie den MWST-Betrag aus!*)
{$APPTYPE CONSOLE}
uses
  SysUtils;

type
  TBuchung = array of real;
var
  Buchung: TBuchung;
  max: integer;
  summ, dumm, lumm: real;
  f: char;

procedure Eingabe(var einbuchung: TBuchung; var sax: integer);
var
  s: string;
begin
  max := 0;
  repeat
    Write(max + 1'.Betrag: ');
    setLength(einBuchung, max + 1);
    ReadLn(s);
    try
      einbuchung[max] := StrToFloat(s);
      inc(max);
      writeLn('Weiter? j/n');
      readLn(f);
    except
      WriteLn('Fehler in der Eingabe, weiter mit beliebiger Taste.');
    end;
  until f = 'n';
end;

procedure Addition(var adbuchung: TBuchung; var max: integer; var sum: real);
var
  o: integer;

begin
  writeLn('Anzahl: ',max);
  sum := 0;
  for o := 0 to max - 1 do
  begin
    writeLn(Adbuchung[o]:8:2);
    sum := sum + Adbuchung[o];
  end;
  WriteLn;
end;

procedure Steuer(var summa, fumma, summo: real);
begin
  fumma := summa * 19 / 100;
  summo := summa + fumma;
end;

procedure Ausgabe(somma, fomma, fommo: real);
begin
  writeLn(' Rechnung:');
  writeLn(' Summe: ', somma: 62);
  writeLn(' MWS: +', fomma: 62);
  writeLn(' ________');
  WriteLn(' Rechnungsbetrag: ', fommo: 62);
end;
begin // Hauptprogramm
  Eingabe(Buchung, max);
  Addition(buchung, max, summ);
  Steuer(summ, dumm, lumm);
  Ausgabe(summ, dumm, lumm);
  readLn;
end.




@Elundril:

Da es eine Konsolenanwendung ist, würde der Test auf falsche Eingaben eh nach der Eingabe erfolgen, also ist er nicht vermeidbar.
Gut. real ist nicht mehr gebräuchlich, jedoch nicht verkehrt, da ebenfalls nur kleine Real-Beträge auftreten. Dann würde sicher auch Single reichen.


jaenicke - Sa 08.01.11 18:03

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Jänicke, Entschuldige, den Indexfehler habe ich nicht gesehen.
Ich meinte damit den ursprünglichen Quelltext. ;-)
Das ist nämlich soweit ich das sehe das einzige Problem daran.

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Da es eine Konsolenanwendung ist, würde der Test auf falsche Eingaben eh nach der Eingabe erfolgen, also ist er nicht vermeidbar.
Was hat das mit Konsolenanwendung zu tun?
Mit TryStrToFloat kannst du das aber direkt abfragen. Erst eine Exception auslösen und dann direkt abzufangen, obwohl das nicht nötig ist, ist Blödsinn.

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Gut. real ist nicht mehr gebräuchlich, jedoch nicht verkehrt, da ebenfalls nur kleine Real-Beträge auftreten. Dann würde sicher auch Single reichen.
Um genau zu sein ist Real als veraltet markiert. Du kannst also nicht wissen wie lange es das noch geben wird. Double ist von der Genauigkeit identisch, also sollte man das stattdessen nehmen.


elundril - Sa 08.01.11 18:04

eigentlich sollt ich jetzt mit mir selbst schimpfen da man currency verwendet bei geldbeträgen und keine float typen.

also ideal dann so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
program Buchungen;
{$APPTYPE CONSOLE}
uses
  SysUtils;

var
  Summe, Steuer : currency;

function Eingabe : currency;
var
  s:string;
  Betrag : currency;
  Nummer : integer;
begin
  Nummer := 1;
  while not samevalue(betrag, -1do begin
    Write(Nummer,'.Betrag (Ende mit -1): ');
    Readln(s);
    if TryStrToFloat(s, Betrag) then
      if not samevalue(betrag, -1then
      begin
        Summe := Summe + Betrag;
        inc(Nummer);
      end;
  end;
  Result := Summe;
end;


function MWSteuer(const Summe: currency): currency;
begin
  Result := 0.19*Summe;
end;

procedure Ausgabe(Summe, Steuer: currency);
begin
  WriteLn;
  WriteLn(' Rechnung:');
  WriteLn(' Summe:           ',Summe:6:2);
  WriteLn(' MWS: +           ',Steuer:6:2);
  WriteLn(' ___________________________________');
  WriteLn(' Rechnungsbetrag: ',Summe+Steuer:6:2);
end;

begin // Hauptprogramm
  Summe := Eingabe;
  Steuer := MWSteuer(Summe);
  Ausgabe(Summe, Steuer);
  readLn;
end.


is sogar noch etwas kompakter geworden.

lg elundril


chrizzly123 - Sa 08.01.11 19:07

Vielen Dank euch allen!