Programm



  • Jochen S. schrieb:

    Noch einfacher ist es, wenn man gleich den Destruktor "manuell" aufruft.

    Das will ich sehen! :p



  • _matze schrieb:

    Jochen S. schrieb:

    Noch einfacher ist es, wenn man gleich den Destruktor "manuell" aufruft.

    Das will ich sehen! :p

    Probiers aus. Es ruft den Destruktor auf, aber das Objekt ist weiterhin zugänglich.

    class MyClass
    {
    public:
    	MyClass() { std::cout << "Objekt erstellt" << std::endl ; }
    	~MyClass() { std::cout << "Objekt gelöscht" << std::endl ; }
    	void DoSomething() { std::cout << "Objekt ruft DoSomething() auf" << std::endl ; }
    };
    
    int main ( )
    {
    	MyClass Obj ;
    	Obj.~MyClass();
    	Obj.DoSomething() ;
    }
    


  • Gut, bei solch einer Klasse mag das ja funktionieren. Wenn du aber irgendwo Speicher reservierst (was ja auch vector tut) und diesem im Destruktor freigibst, kannst du nicht mehr ohne weiteres mit den Objekt arbeiten. Und knivil sagte, dass der Speicher im Destruktor von vector freigegben wird:

    knivil schrieb:

    Auch das manuelle Loeschen der Elemente am Ende ist ueberfluessig, das passiert automatisch, wenn der Destruktor von std::vector aufgerufen wird.

    Da dachte ich, dass man ja auch den Destruktor manuell aufrufen könne. In dem Fall würde also tatsächlich der Speicher freigegeben. Ein Weiterarbeiten mit dem Objekt wäre in dem Falle nicht mehr möglich.



  • Jochen S. schrieb:

    Ein Weiterarbeiten mit dem Objekt wäre in dem Falle nicht mehr möglich.

    Doch, aber mit undefiniertem Verhalten zur Laufzeit. Und das ist ja das Schlimme. pumuckl hat völlig Recht. Ausser bei seltenen Spezialfällen, wenn man auch Placement New verwendet, ruft man nie Destruktoren manuell auf. Entweder wird das Objekt über delete oder automatisch zerstört.

    Falls man vorzeitig den Speicher freigeben möchte, was meistens keine gute Idee ist, kann man immer noch den swap() -Trick anwenden:

    std::vector().swap(my_vector);
    

    Übrigens: Äusserst kreativer Threadtitel. 🤡



  • servus jungs. 👍

    ich muss zugeben ich bin sprachlos, und irgendwie ist das mir auch ein wenig zu hoch geworden 😞 ich kenn micht nicht mehr aus.
    Würde dieses Programm gern lauffähig machen. beim ausführen bekomme ich immer diese Fehlermeldung:

    Kompilierung läuft...
    Lagersystem.cpp
    C:\Dokumente und Einstellungen\Markus\Desktop\Lagersystem\Lagersystem.cpp(48) : error C2374: 'loop' : Neudefinition; Mehrfachinitialisierung
    C:\Dokumente und Einstellungen\Markus\Desktop\Lagersystem\Lagersystem.cpp(37) : Siehe Deklaration von 'loop'
    Fehler beim Ausführen von cl.exe.
    EInlaufkurven.obj - 1 Fehler, 0 Warnung(en)

    bin ratlos!!!!!!!!!!!!!
    Hab ich aber das Prinzip schon richtig geschnallt, dass die 2 Lösung besser auf Änderungen in der Liste reagiert. dh. wenn zb. eine neue art.nummer + Lagernummer hinzukommt,könnte ich die einfach dahinter anreihen.
    Beim nächsten ausführen wird diese Zahl mit ins prog integriert.!!!!!??????

    Gruss



  • Zeig doch mal, wie dein aktueller Code aussieht. Das ist ein eher kleiner Fehler, den du da bekommst.



  • Hallo,
    Hast Du etwas an dem Quelltext geändert? Bei mir lässt sich das Programm ohne Fehler kompilieren. Ich weiss ja nicht, welchen Compiler du benutzt, aber eigentlich dürfte es keinen Compiler geben, der den Code nicht kompiliert.
    Was du tun könntest, wäre folgendes:
    Du deklarierst loop gleich am Anfang von main() :

    int main()
    {
    int loop;
    // ... 
    }
    

    In den For-Schleifen müsstest du dann immer anstatt int loop = ... einfach nur loop = ... schreiben. Aber für konkrete Vorschläge müsste ich Einsicht in den Quelltext haben.

    MfG, Jochen



  • habs jetzt mal so gemacht wie dus im vorherigen beitrag geschrieben hast:

    #include <string>
    #include <iostream>
    #include <fstream>
    #include <vector>
    using namespace std;

    struct SElem
    {
    string Artikelnummer;
    string Lagernummer;
    };

    int main()
    {
    int loop;
    ifstream dat_ein;
    dat_ein.open("datei.txt",ios_base::in);

    vector<SElem> Elemente;

    while(!dat_ein.eof())
    {
    SElem tmp;
    dat_ein >> tmp.Artikelnummer;
    dat_ein >> tmp.Lagernummer;
    Elemente.push_back(tmp);
    }

    int Anzahl = Elemente.size();

    dat_ein.close();

    string ArtNum;
    bool found = false;
    cout << "Artikelnummer: ";cin >> ArtNum;
    cout << "Lagernummer: ";

    for(loop=0;loop<Anzahl;loop++)
    {
    if(Elemente[loop].Artikelnummer==ArtNum)
    {
    cout << Elemente[loop].Lagernummer;
    found = true;
    break;
    }
    }
    if(found==false)cout << "(nicht gefunden)" << endl;
    cin.get();
    for(loop=0;loop<Anzahl;loop++)Elemente.erase(0);
    return 0;
    }

    Das kompilieren funktioniert ohne fehler. beim anschließenden ausführen erscheint folgende fehlermeldung.

    --------------------Konfiguration: test - Win32 Debug--------------------
    Kompilierung läuft...
    test.cpp
    C:\Dokumente und Einstellungen\Markus\Desktop\test\test.cpp(48) : error C2374: 'loop' : Neudefinition; Mehrfachinitialisierung
    C:\Dokumente und Einstellungen\Markus\Desktop\test\test.cpp(37) : Siehe Deklaration von 'loop'
    Fehler beim Ausführen von cl.exe.

    test.exe - 1 Fehler, 0 Warnung(en)



  • Also, ich hab jetzt mal den Quelltext kopiert. Liess sich porblemlos kompilieren. Was hast du denn für einen Compiler? Ich bin jetzt etwas ratlos, aber du könntest ja mal versuchen, für jede Schleife eine andere Schleifenvariable zu nehmen, also:

    erste Schleife: for(int loop1=0;...)
    zweite Schleife: for(int loop2=0;...)
    ...
    Nicht vergessen, dann auch in der Schleife die anderen Variablen zu nehmen.
    Mal sehen, vielleicht klappt es dann.
    Was du noch machen solltest:
    Entferne die Schleife zwischen cin.get(); und return 0; am Ende de Programms.
    Bei mir hängt sich das Prgramm in dieser Schleife immer auf.

    MfG, Jochen



  • jetzt funktionierts. Habs einfach nochmal ganz neu gemacht.Habe noch einige Fragen dazu:

    -Woher weiss denn das Programm das sich erste Spalte in der datei.txt sich auf die Artikelnummer bezieht.

    - was wäre wenn die Lagernummer auch buchstaben enthalten würde. Müsste ja irgendwo deklariert werden oder???

    -ist ein Einbezug mit einer anderen datei auch möglich. zb. excel datei??

    -wie würde sich das Programm ändern wenn ich zb. noch eine dritte oder sogar eine 4. Info dazuhaben möchte. zb. Anzahl und Artikelbeschreibung



  • So, ich versuche mal, deine Fragen zu beantworten.

    Zur ersten Frage:

    SElem tmp;
    dat_ein >> tmp.Artikelnummer;
    dat_ein >> tmp.Lagernummer;
    Elemente.push_back(tmp);
    

    Das Programm liest immer zwei strings hintereinander ein, die durch Leerzeichen, Tabulatoren, Zeilenumbrüche etc. getrennt sind. Den ersten string sieht das Programm dabei als Artikelnummer an, den zweiten als Lagernummer. Die beiden strings werden in die jeweiligen Elemente der Struktur gespeichert und in den vector Elemente aufgenommen. Dies wird solange gemacht, wie die Bedingung !dat_ein.eof() erfüllt ist. (Also solange, wie das Programm Datensätze findet.) Artikelnummern und Lagernummern wechseln sich in der Datei beginnend mit der Artikelnummer ab.

    Zur zweiten Frage:
    Du kannst in der Artikelnummer sowohl Zahlen als auch Buchstaben verwenden, da strings sowohl zahlen als auch Buchstaben enhalten können (Wäre ja sinnlos, wenn sie es nicht könnten). Eine Anpassung des Programms ist also nicht erforderlich. Allerdings musst du, wenn du Buchstaben verwendest, eventuell Groß/Kleinschreibung beachten.

    Zur dritten Frage:
    Da Excel-Dateien anders aufgebaut sind als die Textdateien, die dieses Programm erwartet, ist es mit diesem Programm nicht möglich, Excel-Dateien auszuwerten. Zu diesem Zweck müsste das Programm modifiziert werden.

    Zur vierten Frage:
    Du müsstest der Struktur SElem noch zwei weitere Elemente hinzufügen, sodass die Struktur in etwa so aussieht:

    struct SElem
    {
    string Artikelnummer;
    string Lagernummer;
    int Anzahl;
    string Beschreibung;
    };
    

    Der Code zum Einlesen der Datensätze müsste dann so aussehen:

    SElem tmp;
    dat_ein >> tmp.Artikelnummer;
    dat_ein >> tmp.Lagernummer;
    dat_ein >> tmp.Anzahl;
    getline(dat_ein,tmp.Beschreibung);
    Elemente.push_back(tmp);
    

    Auch die Ausgabe muss so angepasst werden, dass das Programm auch die neuen Informationen anzeigt.

    Hier nochmal das angepasste Programm:

    #include <string>
    #include <iostream>
    #include <fstream>
    #include <vector>
    using namespace std;
    
    struct SElem
    {
    string Artikelnummer;
    string Lagernummer;
    int Anzahl;
    string Beschreibung;
    };
    
    int main()
    {
    ifstream dat_ein;
    dat_ein.open("datei.txt",ios_base::in);
    
    vector<SElem> Elemente;
    
    while(!dat_ein.eof())
    {
    SElem tmp;
    dat_ein >> tmp.Artikelnummer;
    dat_ein >> tmp.Lagernummer;
    dat_ein >> tmp.Anzahl;
    getline(dat_ein,tmp.Beschreibung);
    Elemente.push_back(tmp);
    }
    
    int Anzahl = Elemente.size();
    
    dat_ein.close();
    
    string ArtNum;
    bool found = false;
    cout << "Artikelnummer: ";cin >> ArtNum;
    
    for(int loop1=0;loop1<Anzahl;loop1++)
    {
    if(Elemente[loop1].Artikelnummer==ArtNum)
    {
    cout << "Lagernummer\t: " << Elemente[loop1].Lagernummer << endl;
    cout << "Anzahl\t\t: "    << Elemente[loop1].Anzahl << endl;
    cout << "Lagernummer\t:" << Elemente[loop1].Beschreibung << endl;
    found = true;
    break;
    }
    }
    if(found==false)cout << "(Keine Informationen gefunden)" << endl;
    cin.get();
    return 0;
    }
    

    Der Inhalt von Datei.txt lautet nun:

    105-10-2467.5	2117   3 Dies ist eine Produktbeschreibung.
    108-48-4757.8	3456   7 Das ist auch eine Produktbeschreibung
    140-47-4564.2	4567   5 Das hier ist Produnkt nummer Drei
    

    Die Datei ist so aufgebaut:
    Artikelnummer1 Lagernummer1 Anzahl1 (Rest der Zeile Produktbeschreibung1)
    Artikelnummer2 Lagernummer2 Anzahl2 (Rest der Zeile Produktbeschreibung2)
    Artikelnummer3 Lagernummer3 Anzahl3 (Rest der Zeile Produktbeschreibung3)
    ...

    Ich hoffe, meine Erklärungen sind hilfreich.

    MfG, Jochen



  • FreakY<3Cpp schrieb:

    Mach aus dem double ein string.
    Dann meinst du, du hast 100 Artikelnummer und dazu passende Lagernummer, da würd ich wohl map empfehlen.
    Und dann noch etwas ganz schlaggebendes
    ES GIBT KEINE IF-SCHLEIFEN!!!

    doch gibt es
    und zwar werden solche konstruktionen if schleifen genannt:

    int main()
    {
    punkt:
       if ( 0 == 0 )
           goto punkt;
    }
    

    das prinzip sollte klar sein, ich weiss nicht obs syntaktisch richtig ist, hab goto nie gelernt (wieso auch xD)



  • Skym0sh0 schrieb:

    doch gibt es
    und zwar werden solche konstruktionen if schleifen genannt:

    int main()
    {
    punkt:
       if ( 0 == 0 )
           goto punkt;
    }
    

    Das hast du dir gerade ausgedacht, oder?



  • Skym0sh0 schrieb:

    und zwar werden solche konstruktionen if schleifen genannt:

    Gib mal 'ne Quelle. :p



  • Skym0sh0 schrieb:

    doch gibt es
    und zwar werden solche konstruktionen if schleifen genannt:

    int main()
    {
    punkt:
       if ( 0 == 0 )
           goto punkt;
    }
    

    Das ist korrekt.



  • Hihi.

    int main()
    {
        // switch-schleife
        label: switch(false) { default: goto label; }
    
        // hallo-schleife
        label: "hallo"; goto label;
    
        // baadf00d-schleife
        label: 0xbaadf00d; goto label;
    }
    


  • Nukularfüsiker schrieb:

    Hihi.

    int main()
    {
        // switch-schleife
        label: switch(false) { default: goto label; }
        
        // hallo-schleife
        label: "hallo"; goto label;
    
        // baadf00d-schleife
        label: 0xbaadf00d; goto label;
    }
    

    Denen bin ich so noch nicht begegnet, aber die "if-Schleifen" habe ich schon oft gesehen. Aber ich nenne sie umständlich "if-goto-Schleifen", unter anderem damit ich nicht mit oben genannter Webseite kollidiere.



  • volkard schrieb:

    Aber ich nenne sie umständlich "if-goto-Schleifen"

    Ist doch fein, da kommt wenigstens das Schleifenkonstrukt drin vor.

    Ansonsten ist mir noch die else-Schleife eingefallen:

    label: if(false); else goto label;
    


  • Nukularfüsiker schrieb:

    Ansonsten ist mir noch die else-Schleife eingefallen:

    label: if(false); else goto label;
    

    Das erste ; gehört da nicht hin.
    EDIT: Natürlich gehört es da doch hin.

    Zusammengefasst: Es gibt keine if -Schleifen, weil man alles zwischen label: und goto label; tun kann.



  • TyRoXx schrieb:

    Zusammengefasst: Es gibt keine if -Schleifen, weil man alles zwischen label: und goto label; tun kann.

    Manche Schleifen haben mehr oder weniger gebräuchliche Namen, die Zeitschleife (eher DOS), die Idiotenschleife (eher 64-er), die Menuschleife (eher DOS), ... und auch eben die If-Schleife (eher C/Basic).


Anmelden zum Antworten