Lottoprogramm läuft unter linux nicht, hängt an einfacher for schleife



  • Hallo,

    Ich habe ein Lottoprogramm geschrieben für die Uni, wie es die meisten von euch bestimmt auch schonmal schreiben mussten.
    Es läuft unter Windows (mit Codeblocks) ohne Probleme allerdings nicht unter Linux mit Codeblocks. Da hängt es sich während der Ergebnisausgabe auf während einer For-Schleife.

    for(i=0; i<12; i++)
    {
    cout << endl << i+1 << "." << "Lottoschein "<< endl << endl;
    for(j=0; j<6; j++)
    {
    cout << " " << lotto[i][j];
    }

    cout << endl;
    }

    Komischerweise funktioniert es unter Windows wenn ich entweder i<13 setze,somit einen leeren 13. Lotteschein ausgebe. Oder aber nur 11. Lottoscheine ausgebe, wenn es allerdings, wie in der Aufgabe gewünscht 12 sein sollen hängt die Schleife sich auf.

    Ich bin bin etwas ahnungslos woran das liegen mag.

    Danke für eure Aufmerksamkeit ich freue mich über jeden Tipp!



  • Verwende bitte Code-Tags und zeig die Definition von lotto.

    Optimal wäre ein kompilierbares Minimalbeispiel.

    Bin mir ziemlich sicher, dass der Fehler nicht Unix-spezifisch ist, auch wenn er dir dort auffällt und unter Windows nicht. Werde dich daher mal verschieben.



  • Dieser Thread wurde von Moderator/in nman aus dem Forum Linux/Unix in das Forum C++ (auch C++0x und C++11) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich hoffe das passt so?

    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main()
    {
        int lotto[12][6];
        int i,j,q,x,k,o,l;
        bool neueZahl;
    
    x = time(NULL);
    
    // Schleife fuer Zeilen, Y-Achse
    for(i=0; i<12; i++)
        {
    
    	// Schleife fuer Spalten, X-Achse
    	for(j=0; j<6; j++)
            {
    
                do
                    {
    
                            x = x ^ (x>>13);
                            x = x ^ (x<<17);
                            x = x ^ (x>>15);
    
                            lotto[i][j] = x % 49 + 1;
    
                            neueZahl = true;
    
                            for (q=0; q<j; q++)
                                {
                                    if (lotto[i][q]==lotto[i][j])
                                        {
                                            neueZahl = false;
                                        }
                                }
                    }
                while (!neueZahl);
            }
    
        }
    
    // Ausgabe
    
    for(i=0; i<12; i++)
        {
            cout << endl  << i+1 << "." << "Lottoschein "<< endl << endl;
            for(j=0; j<6; j++)
            {
    		cout << "  " << lotto[i][j];
            }
    
            cout << endl;
        }
    }
    


  • Ich sehe da auf den ersten Blick nichts auffälliges. Kannst du nicht einfach den Debugger benutzen um festzustellen, wo sich das Programm aufgehängt hat?



  • ot:

    uhm, das ist also das c++, welches man an unis lernt? puh, gott sei dank bin ich noch nicht in dem altersbereich...

    wenn du schon eine xor-shift-implementierung abkopierst (?), dann solltest du auch die korrekten (nämlich die vorzeichenlosen) datentypen kopieren.

    was dein code genau macht schaue ich mir nicht an, das zeug mit "i,j,q,x,k,o,l" versteht ja kein mensch. um leserlichen code zu schreiben solltest du variablen so lokal wie möglich definieren (in vielen fällen hier im for-header) und dann auch mit richtigen bezeichnern benamsen. dann solltest du ebenfalls keine magical numbers übers ganze programm verstreuen sondern sie einmal zentral festhalten (z.b. mit unnamed enums oder mit konstanten variablen). ausserdem sehe ich den sinn nicht wieso du so unzählige male std::cout flushen willst. es gibt ausserdem in c++ operatoren, die einen binären operator und eine zuweisung kopieren (also x ^= y statt x = x ^ y). und bitte rück mal konsistent ein.



  • Nach der Ausgabe der Lottozahlen läuft das Programm nicht weiter, im eigentlichen Programm folgt eine Auswertung der Tippscheine. Diese wird unter windows durchgeführt auf Linux allerdings bleibt das Programm wohl in der Schleife hängen. Ich habe versucht nach der letzten Schleife ein einfach "hello world" auszugeben, aber es kommt nichts. Deshalb gehe ich davon aus, das es an der Schleife liegt.

    Gruß



  • Meganoob schrieb:

    Nach der Ausgabe der Lottozahlen läuft das Programm nicht weiter, im eigentlichen Programm folgt eine Auswertung der Tippscheine. Diese wird unter windows durchgeführt auf Linux allerdings bleibt das Programm wohl in der Schleife hängen. Ich habe versucht nach der letzten Schleife ein einfach "hello world" auszugeben, aber es kommt nichts. Deshalb gehe ich davon aus, das es an der Schleife liegt.

    Gruß

    Die Schleife ist ja extrem verschachtelt. Das kann überall sein und durch den Code blickt hier offenbar niemand durch. Versuche bitte, den Fehler weiter einzugrenzen entweder mit dem debugger oder mit weiteren Ausgaben



  • Oder meintest du die letzte Schleife? Da kann mit den Abbruchkriterium nichts falsch sein. Das ist nicht das Problem.



  • @asfdlol

    Danke für die Tipps ich werde versuchen sie umzusetzen, was mir aber direkt neue Probleme einbringt 😞

    Wenn ich Xor-Shift mit dem Datentyp unsigned short int intialsiere, passiert garnichts mehr.
    😕

    Das war doch was du meintest, oder?

    Grüße



  • Das Problem ist wahrscheinlich das Erstellen der Zufallszahlen. Wenn x zu Beginn gleich 0 ist, bleibt x die ganze Zeit 0, sodass das Programm nicht mehr aus der While-Schleife kommt.

    time() liefert bei Linux vllt um Faktor 1000 größere Werte als bei Windows? Oder der Ausführungszeitpunkt war so besonders, dass x einen Wert bekam, bei dem das Programm bzw. die while-Schleife nicht terminiert.



  • Ich hab da auch nichts direkt fehlerhaftes gefunden... ich würde vermuten dass deine Abstürze davon kommen dass du u.U. halt deine 12 zu generierenden Lottoscheine in der Ausgabe auf 13 erhöht hast aber in der Generierung nicht - oder im Array welches die Scheine beinhaltet?! Ich hab's dir hier mal simpel als #define hinterlegt. Ansonsten hab ich nicht wirklich was geändert, paar Kleinigkeiten gesäubert bzw. eben als Methode/Funktion ausgelagert. Wieso man es erst in ein Array packt um es dann grad mal auszugeben ist vermutlich Vorgabe durch die Ausgabe?!

    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    #include <iomanip>
    #include <sstream>
    
    using namespace std;
    
    #define TICKETS 50
    
    void fillTicket(unsigned short *ticket)
    {
    	unsigned int x = rand(), i=0;
    	bool unique=true;
    
    	while (i<6)
    	{
    		x^=(x>>13);
    		x^=(x<<17);
    		x^=(x>>15);
    		ticket[i]=x%49+1;
    
    		for (unsigned int n=0;n<i;n++)
    		{
    			if (ticket[n]==ticket[i])
    			{
    				unique=false;
    				break;
    			}
    		}
    
    		if (unique)
    			i++;
    		else
    			unique=true;
    	}
    }
    std::string showTicket(unsigned short *ticket)
    {
    	std::stringstream rt;
    	for (int i=0;i<6;i++)
    		rt << setw(3) << ticket[i];
    	return rt.str();
    }
    
    int main()
    {
    	unsigned short lotto[TICKETS][6];
    
        for (int i=0;i<TICKETS;i++)
        	fillTicket(lotto[i]);
    
        for (int i=0;i<TICKETS;i++)
        {
            cout
            	<< setw(10)
            	<< i+1
            	<< ". Lottoschein: "
            	<< showTicket(lotto[i])
            	<< endl;
        }
    }
    


  • Bist Du Dir sicher, daß es nicht schon bei der Erstellung der Lottozahlen hängt? Dein "Zufallszahlengenerator" könnte nämlich die Ursache sein. Bei mir funkt es aber. Time liefert ja auch Werte von ca. 1,3 Mrd. Das sollte passen.

    mfg Martin



  • Meganoob schrieb:

    @asfdlol

    Danke für die Tipps ich werde versuchen sie umzusetzen, was mir aber direkt neue Probleme einbringt 😞

    Wenn ich Xor-Shift mit dem Datentyp unsigned short int intialsiere, passiert garnichts mehr.
    😕

    Das war doch was du meintest, oder?

    Grüße

    Von short hat er nicht gesprochen. Vorzeichenlos war das Attribut, das er nannte. Mit jeder Verkürzung von x steigerst Du die Wahrscheinlichkeit, daß es irgendwanneinmal 0 wird. Dann hast Du Deinen Hänger. Weil dann nur noch 0 von Deinem "Zufallsgenerator" geliefert wird.

    Meistens werden Shiftoperatoren auf vorzeichenlose Typen angewendet. In diesem Fall ist es aber nicht erforderlich. Ganz iom Gegenteil, ich denke sogar, daß es besser ist. Denn

    Wenn x vor dem ersten shift negativ ist, werden die höchstwertigen 13 Bits invertiert, ansonsten werden sie nicht verändert.

    Am besten, Du untersuchst, welche Schleife genau zum Hänger führt. Vielleicht ist es sinnvoll, noch eine Prüfung, ob x 0 geworden ist so alla:

    if ( x== 0 ) x = time( NULL );

    mfg Martin



  • Die Wahrscheinlichkeit dass es der "Zufallsgenerator" ist, ist meines Erachtens ziemlich gering - das Design über den Zufallsgenerator direkt ist dennoch nicht das wahre.
    Wie ich schon sagte würde ich die Fehlerquelle eher im verändern der Arraygröße vermuten da er ja alles statisch mit 12 festgelegt hat.
    Einfache Lösung: #define (wie in obigem Beispiel),
    Bessere Lösung: als parameter die Anzahl der zu generierenden Scheine auslesen und dann eben umsetzen.. (Stickwort new)

    Leider ist über die Aufgabenstellung konkret auch nichts bekannt - also was vorgegeben ist und was nicht. Das wären:

    - Zufallsgenerator-Design: Wieso nicht ein Array mit 1 bis 49 als Wert und dieses "shufflen": http://www.cplusplus.com/reference/algorithm/random_shuffle/, dieses Array einmal in der main bauen und jeweils als Pointer mit übergeben... so kann es immer und immer wiederverwendet werden ohne viel Mehraufwand. Die Laufzeit wäre linear und definitiv besser als der Spass den du da treibst. Du kannst soviel random und shift betreiben wie du lustig bist, a) sind die Zahlen durch die konstanten shifts in gewisser weise "vorgegeben" bzw. haben einfach eine Verteilung mit Schwerpunkt - genau das was man bei "Zufallszahlen" ja vermeiden will. b) Viel Aufwand dafür dass du später ein modulo 49 darauf anwendest um wieder in der Lotto-Range zu sein...

    - Speichern-/ Ausgeben: Wieso erst in einem riesigem Mehrdimensionalen Array speichern wenn man einfach in einer Schleife jeweils einen Lottoschein "on the fly" erstellen und ausgeben kann - danach interessiert das Ergebnis ja keinen mehr.


Anmelden zum Antworten