Suche Hilfe bei der Programmierung eines IBAN-Rechners



  • Hallo!
    Bin ganz neu hier und erhoffe mir durch das Forum mein Problem zu lösen. Ich bin dabei, um C++ etwas mehr zu lernen, einen IBAN Rechner zu programmieren. Ich hänge an dem Punkt, die BBAN als String in einen Integer zu wandeln, um diesen Wert dann mit Modulo 97 zu berechnen. Hier mal mein Code:

    Header:

    #pragma once
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <cerrno>
    using namespace std;
    
    //Variablen:
    string skontoNr;
    string sblz;
    long int ibban;
    string sbban;
    string sLandKenn;
    string sNull = "00";
    char eingabe;
    string sLandNum;
    
    

    main:

    include <iostream>
    #include <sstream>
    #include "IBAN.h"
    int main() {
    
    	cout << "*****************Willkommen im IBAN-Rechner!*****************" << endl;
    	cout << "Um Ihre IBAN zu errechnen benoetigen wir einige Informationen von Ihnen.Darunter das Land aus welchem Sie kommen : " << endl;
    	cout << "1. Deutschland\n 2. Oesterreich\n 3. Schweiz\n";
    	cout << endl;
    	cin >> eingabe;
    
    	switch (eingabe)
    	{
    	case '1':
    		sLandKenn = "DE";
    		sLandNum = "1314";
    		break;
    	case '2':
    		sLandKenn = "AT";
    		sLandNum = "1029";
    		break;
    	case '3':
    		sLandKenn = "CH";
    		sLandNum = "1217";
    	default:
    		cout << "Zur Zeit stehen leider nur diese 3 Laender zur Auswahl." << endl;
    		break;
    	}
    	cout << "Nun benoetigen wir noch Ihre Kontonummer, sowie Ihre BLZ: " << endl;
    	cout << endl;
    	cout << "Kontonummer: " << endl;
    	cin >> skontoNr;
    	cout << "BLZ: " << endl;
    	cin >> sblz;
    
    	//Erstellung der BBAN
    	sbban = sblz + skontoNr + sLandNum + sNull;
    	cout << sbban << endl;
    
    	//Konvertierung in int
    	ibban = stol(sbban); // <--  Folgender Fehler kommt hier raus: Unbehandelte Ausnahme bei 0x740C45A2 in IBAN.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x00DDF940.
    
    	cout << ibban << endl;
    	
    
    	return 0;
    }
    

    Sorry wenn ich es in die Falsche Kategorie geschoben habe.
    Danke schon mal 🙂



  • @revo94
    Variablendefinitionen im Header? Ist das Dein Ernst? Das ergibt früher oder später Probleme. Wenn Du globale Variablen nicht brauchst, dann nutze es nicht sondern definiere sie so lokal wie möglich.

    Zu Deiner nicht gestellten Frage: Die IBAN ist zu groß, um sie in einer long variable zu speichern.

    Edit: Das da

    using namespace was auch immer;
    

    in einem Header gewöhnst Du Dir auch ganz schnell wieder ab.



  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    Die Iban dürfte wohl zu lang sein. Die grösste Zahl, die long aufnimmt ist 2147483647. Die grösste Zahl, die long long aufnimmt ist 9223372036854775807. Eine Iban hat immer noch eine Stelle mehr.



  • Also meine IBAN sieht vom Format irgendwie ganz anders aus, die beginnt mit DE... aber abgesehen davon: was wird bei sbban ausgegeben (also eine Zeile vor dem Crash)? Als nächstes kannst du dann nachschauen, welchen Wertebereich ein "long int" abdecken kann.



  • @mgaeckler Danke erst mal... Hätte mir ehrlich gesagt nettere Antworten erwartet 😃 Aber hey, im Internet kann man sowas wohl vergessen.... Wie auch immer... Das

    using namespace std;
    

    hat man bei uns so an der Hochschule gezeigt bekommen.

    Und danke, jetzt weiß ich das der Datentyp falsch ist 👍
    Und das mit der Variablen Definition... Ist dafür nicht der Header da? 🤔

    Bitte belehre mich eines Besseren!



  • @daddy_felix Klar, die IBAN fängt auch mit einem Länderkürzel an... Ich bin ja noch nicht fertig 😃 Aber bevor man die IBAN hat, erhält man die BBAN die sich durch BLZ + Kontonummer und dem Länderkürzel+00 ergibt.



  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    Und das mit der Variablen Definition... Ist dafür nicht der Header da?
    Bitte belehre mich eines Besseren!

    Nein

    1. globale Variablen sollte man vermeiden
    2. wenn du den Header in zwei cpp-Dateien verwendest, hast du jede Variable zweimal definiert => Fehler


  • @manni66 1. Richtig wären also getter und setter?
    2. Habe ich schon herausgefunden und mich geärgter woher der Fehler kam ^^

    Dann verstehe ich den Sinn von Header Dateien nicht. Muss ich noch mal die Folien durchgehen.

    Danke



  • Schalt mal deine Warnung im compiler an

    Ich vermute

    stol(sbban)
    

    wirft eine Warnung



  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    1. Richtig wären also getter und setter?

    Nein. Ob du die globalen Variablen jetzt direkt anfasst oder das Ganze hinter einem Funktionsaufruf versteckst spielt keine Rolle.



  • @manni66 Wie wäre es denn richtig? Ich stehe wirklich noch am Anfang des Programmieren. Ich weiß dass globale Variablen scheiße sind, aber 1. weiß ich nicht ob es in meinem Fall schon Sinn macht es anders zu schreiben und 2. weiß ich nicht wie man es richtig macht.



  • @revo94
    Das using namespace std; im Header führt das ganze namespace-Konzept ad absurdum. Das wird nur von Leuten gemacht, die namespaces nicht verstanden haben oder einfach nur zu faul sind. Das kann man für Mini-Projekte/Aufgaben machen, wenn man weiß, welche Probleme man sich damit einhandelt.
    Angenommen, du hast zwei Bibliotheken LibA und LibB, beide definieren ihren eigenen namespace liba und libb und exportieren einen Datentyp SomeType (also liba::SomeType und libb::SomeType).

    In deinem Projekt gibt es jetzt eine .h Datei:

    #include "liba/types.h"
    
    using namespace liba;
    
    struct MyStruct
    {
       SomeType data; // liba::SomeType
    };
    

    und eine andere .h Datei

    #include <libb/types.h>
    
    using namespace libb;
    
    struct AnotherStruct
    {
       SomeType data;
    };
    

    Beide TUs lassen sich separat ohne Probleme übersetzen.

    In einer dritten Datei hast du jetzt sowas:

    #include "mystruct.h"
    #include "anotherstruct.h"
    ...
    

    Und da geht das in die Hose. Nach dem include von "mystruct.h" ist der namespace liba geöffnet, weil in der .h Datei ein using namespace liba steht. Anschließend guckt sich der Compiler anotherstruct.h an und findet dort SomeType. Weil zuvor ebenfalls der namespace libb geöffnet wurde ist die Deklaration mehrdeutig und führt zu einem Fehler. using namespace im Header kann also zu Nebeneffekten und Fehlern in anderen TUs führen, und deswegen macht man das einfach nicht.



  • @firefly Die habe ich im Code als Kommentar angehängt 🙂

    Unbehandelte Ausnahme bei 0x740C45A2 in IBAN.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x00DDF940.
    


  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    Ist dafür nicht der Header da?

    Der Header ist als Schnittstelleninformation für den Compiler gedacht.

    Wenn du in einer .cpp Datei (Quellcode) Funktionen aus einer anderen .cpp benutzen möchtest, braucht der Compiler Informationen darüber (Name, Rückgabewert Aufrufparamter).
    Dies sind aber nur Deklarationen.

    Und auch nur die Informationen, die woanders gebraucht werden, gehören in den Header.



  • @DirkB Also kommen die Variablen die ich in einer .cpp benötige, in die .cpp selbst?



  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    @firefly Die habe ich im Code als Kommentar angehängt 🙂

    Unbehandelte Ausnahme bei 0x740C45A2 in IBAN.exe: Microsoft C++-Ausnahme: std::out_of_range bei Speicherort 0x00DDF940.
    

    Nein! Das ist keine Compiler Warnung. Die ausgabe passiert wenn du dein Programm laufen lässt



  • @firefly Okay... sorry, ich weiß jetzt nicht wirklich wo das in Visual Studio geht.



  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    @DirkB Also kommen die Variablen die ich in einer .cpp benötige, in die .cpp selbst?

    Ja natürlich.
    Am Besten noch in die Funktion (auch main ist eine Funktion) in der du sie als erstes (dem Aufruf nach) benötigst.
    Der Rest wird über Funktionsparamter weiter gegeben.

    Wenn du eine Variable doch mal in einer anderen .cpp benötigst, wird sie mit extern im Header deklariert.



  • @DirkB Danke für deine Geduld mit mir und natürlich für deine Tipps!



  • @revo94 sagte in Suche Hilfe bei der Programmierung eines IBAN-Rechners:

    @firefly Okay... sorry, ich weiß jetzt nicht wirklich wo das in Visual Studio geht.

    Was weißt du nicht?
    Der Unterschied zwischen Compiler Fehler (evtl auch Linker Fehler) und ein Fehler der zur Laufzeit des Programms entsteht?

    Du kannst ein Programm übersetzten (Compilieren)
    Du kannst ein Programm bauen (compilieren und linken)
    Und du kannst ein Programm laufen lassen (Run)

    Visual Studio kann das alles automatisch nacheinander ausführen.
    Dennoch bleiben es getrennte Aktionen.


Anmelden zum Antworten