mikrocontroller.net

Forum: PC-Programmierung C Programmieren (Kassenautomat)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von TerrysPC (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Hallo zusammen!

Ich versuche gerade einen Kassenautomaten zu programmieren, der die Zahl 
der Scheine, Münzen und Cent Stücke ausgeben soll, sowie den jeweiligen 
Restbetrag. Dazu sollen die Zwischenwerte in Arrays gespeichert werden 
und es soll struct verwendet werden. Die Funktion an sich funktioniert 
ohne das struct und das Zwischenspeichern, nur mit den jeweiligen 
Bedingungen leider nicht und ich finde meinen Fehler nicht. Denn die 
Ausgabe der Zahlenwerte erfolgt nicht, es erscheint immer nur "nan" und 
ich weiß nicht warum. Ich würde mich freuen, wenn ihr mal über das 
Programm schaut und mir weiterhelfen könnt.

Mein Programm sieht wie folgt aus:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>



struct Geld{
    float Geldeinheiten[20];
    float anzahl[20];
    float Restsumme;
};


   struct Geld Summe(float a, float b)
{
    struct Geld Geldeinheiten;
    float n;
    int i;
    float scheine[7]={500,200,100,50,20,10,5};
    float muenzen[2]={2,1,};
    float cent[6]={0.50,0.20,0.10,0.05,0.02,0.01};
    int arrays[7]={};
    int arraym[8]={};
    int arrayc[6]={};




     for(i=0;i<7;i++)
        {


            printf(" %3.2f x:  %3.2f\n",n/scheine[i],scheine[i]);
            n=fmodf(n,scheine[i]);
            printf("%3.2f  ",n);
            arrays[i]=n/scheine[i];
            //Geldeinheiten.anzahl[i]=n%scheine[i];
        }

    for(i=0;i<8;i++)
        {
        printf(" %3.2f x:  %3.2f\n",n/muenzen[i],muenzen[i]);
        n=fmodf(n,muenzen[i]);
        printf("%3.2f  ",n);
        arraym[i]=n/muenzen[i];
        }

    for (i=0;i<6;i++)
        {
        printf(" %3.2f x:  %3.2f\n",n/cent[i], cent[i]);
        n=fmodf(n,cent[i]);
        printf("%3.2f  ",n);
        arrayc[i]=n/cent[i];
        }

  printf("\n");
  return Geldeinheiten;
}




int main()
{
    struct Geld Geldeinheiten;
    float n;
    struct Geld y;
    float scheine[7]={500,200,100,50,20,10,5};
    float muenzen[2]={2,1,};
    float cent[8]={0.50,0.20,0.10,0.05,0.02,0.01};
    int arrays[7]={};
    int arraym[8]={};
    int arrayc[6]={};

    printf("Eingabe des zu zahlenden Betrags");
    scanf("%f",&n);

    y= Summe(scheine[7],muenzen[8]);
    printf(" ",y);
    Geldeinheiten.anzahl[20]=arrays[7],arraym[8],arrayc[6];
    printf("  ",Geldeinheiten.anzahl[20]);

return 0;


}


Vielen Dank!

LG TerrysPC

von Dirk B. (dirkb2)


Bewertung
2 lesenswert
nicht lesenswert
Der Compiler gibt zur Ausgabezeile sicher eine Warnung aus.
Wenn nicht, erhöhe den Warnlevel.

Bei Geldbeträgen rechne in Cent. Da gibt es keine Rundungsfehler.
float ist da extrem ungeeignet.

Den Bezeichner n nimmt man gewöhnlich für Ganzzahlen.

Bei printf("%3.2f  ",n); steht die 3 nicht für den Vorkommaanteil 
sondern für die Gesamtzahl der Zeichen (mit Komma)

Bei y= Summe(scheine[7],muenzen[8]); übergibst du die Elemente mit dem 
Index 7 bzw 8. Die existieren jedoch gar nicht.

Zudem benutzt du diese Werte (a undb) in Summe auch gar nicht.

Das n aus main kommt auch nirgends mehr vor.

von foobar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ein Problem (wohl die Ursache der NaNs) ist:
   ...
   float muenzen[2]={2,1,};
   ...
   for(i=0;i<8;i++)
   {
        printf(" %3.2f x:  %3.2f\n",n/muenzen[i],muenzen[i]);
        n=fmodf(n,muenzen[i]);
        printf("%3.2f  ",n);
        arraym[i]=n/muenzen[i];
    }
    ...

Die 8 ist zu groß, du greifst auf Speicher außerhalb des Arrays zu.
Außerdem scheint mir die Reihenfolge des fmodf und der Division 
verkehrt.

Weiter: Arithmetik mit nicht-ganzzahligen Fließkommazahlen ist nicht 
trivial (0.1 z.B. ist nicht exakt darstellbar) und du handelst dir 
überall Rundungsfehler ein.  Einfacher wird es mit Ganzzahltypen, dann 
in Cent statt Euro.

von Dirk B. (dirkb2)


Bewertung
1 lesenswert
nicht lesenswert
TerrysPC schrieb:
> Geldeinheiten.anzahl[20]=arrays[7],arraym[8],arrayc[6];

Arrays kann man nicht zuweisen.
Der Kommaoperator wirkt anderes als du vermutest.
Du gibst hier auch nicht ganze Arrays an, sondern einzelne Elemente die 
auch gar nicht existieren.

von Eric B. (beric)


Bewertung
0 lesenswert
nicht lesenswert
#include <stdio.h>

int give_euros(int amount, int unit)
{
    int nr_of_euros = amount / (unit * 100);
    if(nr_of_euros > 0) {
        printf("%5dx %3d euro\n", nr_of_euros, unit);
    }
    return nr_of_euros * unit * 100;
}

int give_cents(int amount, int unit)
{
    int nr_of_cents = amount / unit;
    if(nr_of_cents > 0) {
        printf("%5dx %3d cent\n", nr_of_cents, unit);
    }
    return nr_of_cents * unit;
}

int main()
{
    float amount;
    printf("amount (in Eur): ");
    scanf_s("%f", &amount);

    int amount_in_cent = (int)(amount * 100);

    static int euros[] = {500, 200, 100, 50, 20, 10, 5, 2, 1};
    for (int i = 0; i < 9; i++) {
        amount_in_cent -= give_euros(amount_in_cent, euros[i]); 
    }

    static int cents[] = {50, 20, 10, 5, 2, 1};
    for (int i = 0; i < 6; i++) {
        amount_in_cent -= give_cents(amount_in_cent, cents[i]); 
    }

    return 0;
}
Hausies erledigt...

: Bearbeitet durch User
von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
TerrysPC schrieb:
> float Geldeinheiten[20];
>     float anzahl[20];

Dirk B. schrieb:
> Bei Geldbeträgen rechne in Cent. Da gibt es keine Rundungsfehler.
> float ist da extrem ungeeignet.

absolut, ich wüsste auch nicht warum Anzahl der Geldeinheiten kleiner 1 
werden soll warum dort float gebraucht wird.

Können deine Geldeinheiten Anzahl Nachkomma haben?

1/2er oder 0,5 20€ Scheine?

TerrysPC schrieb:
> der die Zahl
> der Scheine, Münzen und Cent Stücke

halbe Münzen, halbe Scheine?

Da würde ich die Münzprüfer aber tauschen wenn die Geld kaputt machen :)

von MaWin (Gast)


Bewertung
0 lesenswert
nicht lesenswert
TerrysPC schrieb:
> Ich versuche gerade einen Kassenautomaten zu programmieren

Hausaufgabe, eh ?

Wie kommst du darauf, daß diese okalen Variablen
struct Geld Summe(float a, float b)
{
    struct Geld Geldeinheiten;
    float n;
    int i;
    float scheine[7]={500,200,100,50,20,10,5};
    float muenzen[2]={2,1,};
    float cent[6]={0.50,0.20,0.10,0.05,0.02,0.01};
    int arrays[7]={};
    int arraym[8]={};
    int arrayc[6]={};
mystischerweise dieselben Werte enthalten werden wie diese:
int main()
{
    struct Geld Geldeinheiten;
    float n;
    struct Geld y;
    float scheine[7]={500,200,100,50,20,10,5};
    float muenzen[2]={2,1,};
    float cent[8]={0.50,0.20,0.10,0.05,0.02,0.01};
    int arrays[7]={};
    int arraym[8]={};
    int arrayc[6]={};
Bloss wegen derselben Namen ?
In der passenden Vorlesung nicht da gewesen ?
nan heisst NotANumber und in deine Fall: uninitialisiert, also noch nie 
einen Wert bekommen.

Die Unterteilung in Scheine, Münzen und cent ist ebenso unsinnig wie 
Geld als float zu betrachten. Rechne in cent, und alle auf einen Rutsch:
int value[]={50000,20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1};
void main(int argc,char *argv[])
{
    int pieces[15];
    int amount=atof(argv[1])*100; // Betrag in Euro
    for(int n=0;amount>0;)
    {
        if(amount>=value[n])
        {
            amount-=value[n];
            pieces[n]++;
        }
        else
        {
           n++;
        }
    }
    for(int n=0;n<sizeof(value)/sizeof(value[0]);n++)
    {
        printf("%d Stück %.02f\n",pieces[n],value[n]/100.0);
    }
}

von Vlad T. (vlad_tepesch)


Bewertung
0 lesenswert
nicht lesenswert
MaWin schrieb:
> Rechne in cent, und alle auf einen Rutsch:

pieces sollte man noch initialisieren.

und man könnte für die Ausgabe für die Werte auch noch ein Namensarray 
definieren und benutzen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.