2012-04-04 5 views
1

Ich habe vorher eine Frage bezüglich der Generierung eines zufälligen Charakters ohne Vorzeichen gestellt und ziemlich gute Vorschläge kamen auf dem Weg, aber aufgrund der Einfachheit, die ich angewendet habe; srand((unsigned)time(NULL)); rand()%256; Zufallszahlen auf nicht signierten Zeichen bleiben "?"

Ich rufe den Srand einmal am Anfang des Programms, aber ich bekomme immer '?' für ein zufälliges Zeichen. Nicht die ganze Zeit, aber die meiste Zeit und das lässt mich meinen Fokus verlieren.

+3

Sie überprüfen den numerischen Wert und sehen, dass es tatsächlich '?' (ASCII-Wert 63) ist? Oder druckst du nur den Charakter? Wenn dies der Fall ist, ist es möglich, dass alle Nicht-ASCII-Werte (wie der Bereich 128-255) als "?" Gedruckt werden. Versuchen Sie, vor dem Drucken in 'int' zu konvertieren. –

+0

Bitte beschreiben Sie, was Sie beobachten, dass Sie denken, dass Sie "?" für zufälliges Zeichen. Besser noch, bitte geben Sie ein ** kurzes **, ** vollständiges ** Testprogramm an. Siehe http://sscce.org/. –

Antwort

9

Wahrscheinlich erhalten Sie immer zufällige Zeichen, dass Ihr Terminal nicht wie gedruckt werden muss und gibt ? aus. Versuchen Sie, sie zu int vor dem Drucken Umwandlung:

std::cout << (int)my_random_char; 
+0

Vielen Dank, das hat mein Problem gelöst. Ich arbeite gerade an Mac würden die Charaktere auf einem Ubuntu Terminal gezeigt werden? – Ali

+2

@rolandbishop: Manche mögen es vielleicht nicht. Es hängt von der Konfiguration des Terminals, dem Zeichensatz ... ab. Wenn Sie zufällige * Zahlen * erzeugen, sollten Sie * Zahlen * nicht Zeichen drucken, und das ist, was die Umwandlung zu 'int' ins Spiel bringt. Wenn Sie echte Zeichen verwenden möchten, sollten Sie nur die druckbare Teilmenge verwenden. –

3

die Werte auf Ihrer Plattform abhängig [128 255] keine gültigen Zeichen auf ihre eigenen sein. Wenn Sie ein zufälliges, druckbares ASCII-Zeichen wünschen, müssen Sie Zeichen im Bereich [32 127] generieren.

Hier ist Code von meiner Antwort auf Ihre andere Frage geändert, nur druckbare ASCII-Zeichen zu wählen.

int main() { 
    std::random_device r; 
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; 
    auto rand = std::bind(std::uniform_int_distribution<char>(' ','~'), 
          std::mt19937(seed)); 

    std::generate_n(std::ostream_iterator<char>(std::cout," "), 25, rand); 
} 
+0

@rolandbishop: Beachten Sie, dass C++ nicht garantiert, dass ein Bereich von Zeichenwerten druckbar ist, aber 32-127 neigt dazu, auf fast allem zu arbeiten. –

+0

Ja, es ist möglich, dass eine Implementierung möglicherweise nicht so kompatibel ist.Obwohl heutzutage alles außer exotischen Systemen ist. – bames53

5

Sie bekommen nicht "?" als ein Zeichen wird es auf diese Weise gedruckt, weil das ausgewählte Zeichen nicht druckbar ist. Drucken Sie es als Ganzzahl und Sie werden sehen, dass der Wert zufällig ist, wie Sie es erwarten würden.

1

Ein paar Dinge zu beachten:

  1. nicht srand() von rand() vor jedem Aufruf rufen Sie. Rufen Sie es einmal an, wenn Ihr Programm startet (wenn Sie das wirklich wollen).
  2. Versuchen Sie die unsignierten Zeichen als Ganzzahlen auszugeben, um zu sehen, was passiert.
+0

sagte schon, dass ich es einmal anriefe ... – Ali

+0

Oh ja ... geh für die ganzen Zahlen dann wie andere auch darauf hingewiesen haben. Scheint die meiste Zeit, dass Sie Werte außerhalb von Ascii-Bereich erhalten, die als "?" auf dem Terminal. – Axel

+0

PS: Und du hast das in deinem Edit richtig hinzugefügt? Ich könnte schwören, dass ich es vorher nicht gesehen hatte. – Axel

1

Nicht signierte Zeichen sind keine Zeichen; Sie sind Bytes. Sie erhalten zufällige Bytes zwischen 0 und 255 (einschließlich), und einige davon (oder die meisten, abhängig von der Codierung) sind keine gültigen Zeichen.

Wenn Sie einen zufälligen Charakter zwischen a und z möchten, zum Beispiel, verwenden Sie so etwas wie

unsigned char c = 'a' + rand() % 26; 

(rand() % 26 ist nicht der empfohlene Weg, dies zu tun, aber es ist gut genug für die meisten Anwendungen. Die Manpage .)

Verwandte Themen