Mein erster Versuch



  • Ich hoffe ich bin hier richtig...

    Wollt euch hier mal meinen ersten C++ Versuch posten, mit der bitte ob die Richtung ok ist und was man verbessern bzw. c++-freundlicher machen könnte?!

    Funktion: verschiedene Benutzer sollen sich anmelden können, Geld auf Ihrem Konto abheben bzw einzahlen. Mehr auch nicht... 🙂

    Was mich noch interessiert:
    - Wie ist es möglich den Inhalt eines Arrays in eine Variable abzulegen? (statt immer account[id] anzusprechen, einmal account = account[id] damit ich dann nur noch auf account zugreifen muss?)
    - Wieso muss ich beim Übergeben eines Arrays an ein Funktion den * mit anhängen? (hab 2 ganz nette Tutorials bezüglich Zeiger durchgemacht, und dachte mir das ichs halbswegs verstanden hab! Vielleicht könnt jemand noch ein paar Worte dazu verlieren?!)
    - Würde gern die Login-Daten in eine Datei auslagern. (Kann mir da jemand ein Tutorial o.Ä. empfehlen?)

    Vielen Dank schonmal vorab!
    Stefan

    #include <iostream> 
    #include <string>
    
    using namespace std;
    
    class account {
     public: int money;
     public: string username, password;
    
     public:
     account() {
      money = 0;
     }
    
     public:
     void pay_in(int amount) {
      money = money + amount;
     }
     public:
     void pay_out(int amount) {
      money = money - amount;
     }
    
    };
    
    void createAccounts (account* a) {
     a[0].username = "Hans";
     a[0].password = "test";
     a[0].money = 1200;
    
     a[1].username = "Peter";
     a[1].password = "test";
    
     a[2].username = "Paul";
     a[2].password = "test";
    }
    
    int login (string name, string pass, account* a) {
     int anzahl;
    
     anzahl = sizeof(a)-1;
     for(int i=0; i<anzahl; i++) {
      if (a[i].username == name && a[i].password == pass) {
       return i;
      }
     }
     return -1;
    }
    
    void clearScreen() {
     cout<<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
    }
    
    void menu(account* login, int id);
    void run_system(account* accounts);
    
    int main() 
    {
     account accounts[3];
     createAccounts(accounts);
     run_system(accounts);
    }
    
    void run_system(account* accounts) {
     clearScreen();
     cout<<"Guten Tag.\nBitte melden Sie sich an!\n";
    
     string username, password;
     cout<<"Bitte Username eingeben: ";
     cin>>username;
     cout<<"Bitte Passwort eingeben: ";
     cin>>password;
    
     int id;
     id = login(username, password, accounts);
     if (id==-1) {
      cout<<"Falsche angaben";
      cin.get();
      main();
     } else {
      menu(accounts, id);
     }
    
    }
    
    void menu(account* login, int id) {
     clearScreen();
     cout<<"\n\nWillkommen "<<login[id].username<<"\nIhr akteuller Kontostand: "<<login[id].money<<"$\n\nKundenmenue:\n1 - Abheben\n2 - Einzahlen\n3 - Abmelden\nWas möchten Sie tun? ";
     int action;
     cin>>action;
    
     int transfer;
     switch(action) {
      case 1:
       cout<<"Wieviel möchten Sie abheben? ";
       cin>>transfer;
       login[id].pay_out(transfer);
       menu(login, id);
      break;
    
      case 2:
       cout<<"Wieviel möchten Sie einzahlen? ";
       cin>>transfer;
       login[id].pay_in(transfer);
       menu(login, id);
      break;
    
      default:
       run_system(login);
      break;
     }
    }
    


  • C++Noob2008 schrieb:

    - Wie ist es möglich den Inhalt eines Arrays in eine Variable abzulegen? (statt immer account[id] anzusprechen, einmal account = account[id] damit ich dann nur noch auf account zugreifen muss?)

    Wie meinst du das genau?
    Also es gibt ja Schleifen, mit denen du ein Array befüllen kannst:

    int a[5];
    
    //Setzt jedes Element des Arrays auf 2
    for(int i = 0;i < 5; ++i)
     a[i] = 2;
    

    C++Noob2008 schrieb:

    - Wieso muss ich beim Übergeben eines Arrays an ein Funktion den * mit anhängen? (hab 2 ganz nette Tutorials bezüglich Zeiger durchgemacht, und dachte mir das ichs halbswegs verstanden hab! Vielleicht könnt jemand noch ein paar Worte dazu verlieren?!)

    Das ist die Verbindung von Arrays und Zeigern. Wobei das nicht so einfach zu trennen ist.

    int a[5]; //Array
    int *pa = a;   //Zeiger, zeigt auf &a[0]
    
    void foo (int* b){ //Übernimmt einen Zeiger auf int
    ...
    }
    
    int main ()
    {
     foo (a); // a ist ein Zeiger auf das erste Element des Arrays, also &a[0]
     foo (pa);
    }
    

    C++Noob2008 schrieb:

    - Würde gern die Login-Daten in eine Datei auslagern. (Kann mir da jemand ein Tutorial o.Ä. empfehlen?)

    ofstream und zum einlesen ifstream:
    http://www.cplusplus.com/reference/iostream/ofstream/

    Zum Code:

    public: int money;
     public: string username, password;
    

    Finde ich unschön das so nebeneinander zu schreiben. Eher so:

    public: 
       int money;
       string username;
       string password;
    
    money = money + amount; //kann man auch so:
    money += amount; //schreiben
    


  • also:

    1. Du kannst die ja mal stdlib zum thema vector anschauen. Das ist flexibler und sicherer (speicherzugriff). damit ist es dann auch einfacher einen neuen "account hinzuzufügen"

    2. Variablen in Klassen sollten wenn möglich nicht public sondern private sein. Der zugriff erfolgt dann über getter und setter methoden (pay_in, pay_out sind solche) stichwort: datenkapselung

    3. das was drakon schon gesagt hast 🙂



  • Also für einen ersten c++ versuch ist das aber schon ganz schön heftig der code.
    Entweder bist ud ein Superhirn oder ein kleiner Schwindler^^
    Egal, zum Thema:

    Bei der Klasse reicht ein "public:" alles was da rein soll kannst du auch unter
    einem public schreiben. Und wenn wir schon in deinem public-Bereich sind, mach die Variablen lieber private und greif über Set- und Get-Methoden auf diese zu.

    Für deine "clearscreen"-Funktion würde ich, wenn du unter Windows programmierst
    lieber den Befehl

    system("cls")
    

    benutzen, auch wenn system nicht gern gesehen ist.

    Desweiteren verstehe ich die Default-Anweisung deines Switch-Blocks nicht richtig.

    default:
       run_system(login);
      break;
    

    Du müsstest als Parameter einen account zurueckgeben, aber anstelle dessen
    übergibst du einen Integer-Wert.

    Würde gern die Login-Daten in eine Datei auslagern. (Kann mir da jemand ein Tutorial o.Ä. empfehlen?)

    Schau dich mal nach fopen() / fclose() um
    Damit ist simplex hantieren in Dateien möglich.



  • C++Noob2008 schrieb:

    Wieso muss ich beim Übergeben eines Arrays an ein Funktion den * mit anhängen?

    Arrays werden nie als wert übergeben (call by value), sondern immer mit einem zeiger (call by reference) auf das erste element des arrays. warum das so ist, brauchst du wohl (noch) nicht zu verstehen.

    edit: tutorials sind nicht das wahre; ein im internet zu findendes fachbuch ist http://www.informit.de/books/c++21/data/start.htm
    sicher ist dieses buch (aus der 21-tage-reihe) nicht das beste, aber für den anfang nett und macht sicher lust auf mehr.



  • Guten Morgen Leute!
    Vielen Dank für die vielen Antworten, damit hätt ich nicht gerechnet!

    Vorab: Es ist tatsächlich meine erste C++ Anwendung, hätte aber wohl dazu sagen müssen das mir das Programieren nicht gänzlich neu ist! Habe vor Jahren mit QBasic angefangen, und bin dann im lauf der Zeit eher auf Websprachen umgestiegen (PHP, JS, ActionScript usw.). Zudem hab ich mir ein mörder C-Einsteiger-Leitfaden durchgelesen und mich dannach an die Arbeit gemacht! Also weder Schwindler noch Superhirn 😉

    - Wie ist es möglich den Inhalt eines Arrays in eine Variable abzulegen? (statt immer account[id] anzusprechen, einmal account = account[id] damit ich dann nur noch auf account zugreifen muss?)

    War speziell in meiner Anwendung so gedacht:

    account accounts[3];
    createAccounts(accounts);
    
    ///// anstatt
    cout<<account[2].username;
    cout<<account[2].password;
    
    // eben sowas
    a = account[2];
    cout<<a.username;
    cout<<a.password;
    

    Arrays werden nie als wert übergeben (call by value), sondern immer mit einem zeiger (call by reference) auf das erste element des arrays. warum das so ist, brauchst du wohl (noch) nicht zu verstehen.

    Das die Übergabe von Arrays so funktioniert nehme ich jetzt einfach mal so hin, aber trotzdem gut zu wissen das das ganze so richtig ist! (Danke auch für das kleine Bespiel @drakon)

    Zum Thema public und private

    public:
       int money;
       string username;
       string password;
    

    Wie lange gilt denn dann das public? Und gibt es ein Standardwert wenn eine Variable in einer Klasse definiert wird, ohne public oder private?

    int bin_ich_private_oder_public;
    
    public:
       int money;
       string username;
       string password;
       void gilt_hier_das_public_auch() {
    
       }
    

    2. Variablen in Klassen sollten wenn möglich nicht public sondern private sein. Der zugriff erfolgt dann über getter und setter methoden (pay_in, pay_out sind solche) stichwort: datenkapselung

    Leuchtet mir ein, und werde ich zukünftig beachten! 😉

    Für deine "clearscreen"-Funktion würde ich, wenn du unter Windows programmierst
    lieber den Befehl system("cls")

    Ich glaub ich hab 2 Stunden nach sowas gesucht, es dann aufgegeben und dann meine etwas unschöne funktion geschrieben! 😉 DANKE!

    Desweiteren verstehe ich die Default-Anweisung deines Switch-Blocks nicht richtig.

    Hmm, müsste doch ein account sein, oder bin ich jetzt falsch?

    void menu(account* login, int id) {
    ...
    ...
    ...
      default:
       run_system(login);
      break;
    ...
    ...
    ...
    }
    

    Vielen Dank nochmal für die konstruktiven Antworten!
    Werd mich so schnell wie möglich wieder an mein Quellcode setzten! 😉 Und dann das 21-Tage Dingens durcharbeiten!

    Grüße
    Stefan



  • C++Noob2008 schrieb:

    Wie lange gilt denn dann das public? Und gibt es ein Standardwert wenn eine Variable in einer Klasse definiert wird, ohne public oder private?

    das public (wie jeder andere zugriffsspezifizierer) gilt so lang, bis ein anderer zugriffsspezifizierer kommt oder die klassendefinition endet. und wenn weder public noch private steht, sind alle folgenden elemtente (bis wieder ein zugriffsspezifizierer kommt) in einer klasse standardmässig private.

    int bin_ich_private_oder_public; //private
    
    public: //alles public
       int money;
       string username;
       string password;
       void gilt_hier_das_public_auch() { //auch das public
    
       }
    

    Desweiteren verstehe ich die Default-Anweisung deines Switch-Blocks nicht richtig.

    Hmm, müsste doch ein account sein, oder bin ich jetzt falsch?

    void menu(account* login, int id) {
    ...
    ...
    ...
      default:
       run_system(login);
      break;
    ...
    ...
    ...
    }
    

    parameter sehen richtig aus

    Und dann das 21-Tage Dingens durcharbeiten!

    nimm das aber jetzt nicht als ein gesetzbuch, die header notation z.b. ist veraltet (statt "<iostream.h>" schreibt man "<iostream>" und dann "using namespace std;" weil so der aktuelle c++ standard ist)


Anmelden zum Antworten