Ausgabe Problem



  • Hallo Leute,

    habe ein Problem und zwar habe ich ein kleines Lotto-Programm geschrieben...
    Man muss eine Zahl eingeben und dann werden so viele Zufallsziehungen gemacht, wie eingegeben und dann sieht man, welche Zahl am häufigsten geozogen worden ist. Ich weis, ich weis, Homogenität der Zufallsgeneratoren... Darum geht es mir aber zur Übung nicht.

    Ich lasse die "random number" ausgeben und mache ein endl - dadurch schiebt sich aber alles relativ schnell nach oben. Was ich gerne hätte, ist, dass es wie auf dem Screenshot aussieht und sich nur die Zahlen rechts neben dem Pfeil ändern und der rest statisch bleibt.

    Screenshot: http://pl.vc/35n4a

    Wie mache ich das am Besten?
    Hier mein Code

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <iostream>
    #include <cstdlib>
    #include <iomanip>
    #include <string>
    
    using namespace std;
    
    int main(void) {
        system("mode con lines=80 cols=50");
        int in, i, random, OneToFifty[50];
        time_t t;
        time(&t);
        srand((unsigned int)t);
    
        cout << "Bitte geben Sie eine Zahl ein: ";
        cin >> in;
    
        system("cls");
    
        cout << "your number: " << in << endl;
        cout << "hit any key to start nuke" << endl;
        fflush(stdin);
        cin.get();
    
        //Alle 50 Stellen im Array 0 setzen
        for (i=1;i<51;i++) {
            OneToFifty[i] = 0;
        }
    
        //Zufallszahl ziehen und gezogene Zahl ausgeben und im Array hochzählen
        for (i=0;i<in;i++) {
            random = rand() % 50 + 1;
            OneToFifty[random]++;
            cout << "random number: " << setw(10) << random << endl;
        }
    
        system("cls");
    
        //Hochgezähltes Array ausgeben
        for (i=1;i<51;i++) {
            cout << "Number: " << setw(2) << i << " -> "  << OneToFifty[i] << endl;
        }
    }
    

    Besten Dank and alle und auf einen Sieg für Deutschland! 😉



  • Meinst du das Tabulatorzeichen \t? "Blabla\tBlabla";


  • Mod

    Der Datenstrom stdout (auf den std::cout gelenkt ist) stellt nur einen abstrakten Strom von Zeichen dar. Von einer Konsole o.ä. weiß der C++-Standard nichts.

    Möglicherweise suchst du betriebssystemspezifische Funkionalitäten wie die die die WinAPI bereitstellt - für Windows. system("cls") könnte dich interessieren.



  • Hallo Jodocus,

    nein das Tabulator-Zeichen meine ich nicht.
    Ich weis nicht wie ich in der for-Schleife die feste Ausgabe integriere. Angenommen ich gebe 5.000 ein, dann wird 5.000 mal "random number: " und die Zahl ausgegeben. Ich möchte aber, dass die 50 festen Zahlen starr bleiben. Also 1-25 links und dann vielleicht ein /t 😉 26-50 und die Anzahl die Ziehungen.
    Eben wie auf den Screenshot zu erkennen ist.

    Es sollen sich aber nur die gezogenen Zahlen ändern, nicht die 1-25 und nicht die 26-50!



  • Dann rufe innerhalb deiner Schleife die Ausgabefunktion auf:

    //Zufallszahl ziehen und gezogene Zahl ausgeben und im Array hochzählen
        for (i=0;i<in;i++)
        {
            random = rand() % 50 + 1;
            OneToFifty[random]++;
    
            system("cls");
    
           //Hochgezähltes Array ausgeben
           for (i=1;i<51;i++) {
             cout << "Number: " << setw(2) << i << " -> "  << OneToFifty[i] << endl;
        }
    

    (das zweispaltig auszugeben mußt du dann entsprechend selber anpassen...)

    Wichtig: Dein Array ist aber um einen Wert zu klein, also

    OneToFifty[51];
    

    Daher am besten dafür eine Konstante anlegen:

    const int MaxNumbers = 51;
    

    und statt dem Magic-Value verwenden.
    Oder aber auf 50 belassen und dafür das Array nullbasiert indizieren!



  • Vielen Dank Th69 für deine Antwort! 👍

    Ich habe das Programm mal so angepasst, wie du es gesagt hast. Das Problem jetzt ist, es flackert wie verrückt. Er zeigt auch nur die Zeichen an bis 20 oder auch mal 23 und lädt dann sofort wieder neu. Woran es liegt, weis ich -> system("cls") in der Schleife... Wie ich es besser mache, leider nicht - wer kann mir hier noch helfen?

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <iostream>
    #include <cstdlib>
    #include <iomanip>
    #include <string>
    
    using namespace std;
    const int MaxNumbers = 51;
    
    int main(void) {
        system("mode con lines=80 cols=60");
        int in, i, random, OneToFifty[51];
        time_t t;
        time(&t);
        srand((unsigned int)t);
    
        cout << "Bitte geben Sie eine Zahl ein: ";
        cin >> in;
    
        system("cls");
    
        cout << "your number: " << in << endl;
        cout << "hit any key to start win lottery" << endl;
        fflush(stdin);
        cin.get();
    
        //Alle 50 Stellen im Array 0 setzen
        for (i=1;i<51;i++) {
            OneToFifty[i] = 0;
        }
    
        //Zufallszahl ziehen und gezogene Zahl ausgeben und im Array hochzählen
        for (i=0;i<in;i++) {
            random = rand() % 50 + 1;
            OneToFifty[random]++;
    
            system("cls");
    
           //Hochgezähltes Array ausgeben
           for (i=1;i<MaxNumbers;i++) {
               if (i<26)
                  cout << "Number: " << setw(2) << i << " -> "  << setw(7) << OneToFifty[i] << setw(5) << " " << "Number: " << setw(2) << i+25 << " -> "  << setw(7) << OneToFifty[i] <<endl;
           }
        }
    }
    


  • Unter Windows könntest du dir mal die Improved Console anschauen, so daß du dann nicht jedesmal den ganzen Bildschirm löschen mußt, sondern nur per SetPosition (oder gotoxy oder wie auch immer die Funktion dort heißt 😉 den Cursor positionierst und nur die Zahlen überschreibst.


  • Mod

    Ein wenig Kritik:

    • void in einer leeren Parameterliste ist überflüssig - hier bei main .
    • Das Seeden in Zeilen 15-17 ist recht umständlich. Warum nicht
    srand( time(0) );
    

    fflush(stdin);

    
    solltest du durch  
    
    

    std::cin.ignore( std::numeric_limitsstd::streamsize::max(), '\n' );

    
    ersetzen können. Das wird alle ungelesenen Zeichen im Puffer von `cin` löschen; wirkt hier aber irgendwie unvollständig, da du keine Fehlerbehandlung für die Eingabe in Zeile 20 gemacht hast.
    *  Zeile 29-32 ist ein klassischer Fall für[ `std::fill` ](http://en.cppreference.com/w/cpp/algorithm/fill):  
    
    

    std::fill( std::begin(OneToFifty), std::end(OneToFifty), 0 );

    
    Es ginge auch mit `fill_n` \- wird aber ohne Magic Constants sicherlich genauso lang.
    *  Warum verwendest du nur alle Elemente ab dem zweiten im Array `OneToFifty` ? Das erste bleibt ungenutzt.
    *  Das If-Statement in der Schleife (Z. 43) ist extrem fragwürdig (und IIRC ein bekanntes Antipattern). Warum nicht gleich einfach bis `std::min(26, MaxNumbers)` hochlaufen - oder direkt `26` , wenn du weißt dass `MaxNumbers >= 26` ?
    
    > Das Problem jetzt ist, es flackert wie verrückt.
    
    Klar. Ein Schleifendurchlauf ist bei dir sehr kurz und wird `system("cls")` sehr oft pro Sekunde ausführen. Nimm Th69s Ansatz.  
    
    > hit any key to start win lottery
    
    Ist auch ein unpassende Beschreibung da Eingaben auf der Konsole (u.a. unter Windows, also deinem System) Zeilenorientiert sind und dein Programm demnach nur nach drücken der Enter-Taste weiterlaufen wird. `getch` könnte eher sein was du suchst.

Log in to reply