Ich möchte eine zufällige Zeichenfolge erstellen, die aus alphanumerischen Zeichen besteht. Ich möchte in der Lage sein, die Länge der Zeichenfolge anzugeben.
Wie mache ich das in C ++?
Mehrdad Afsharis Antwort würde den Trick machen, aber ich fand es etwas zu ausführlich für diese einfache Aufgabe. Nachschlagetabellen können manchmal Wunder bewirken:
void gen_random(char *s, const int len) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}
s[len] = 0
ist falsch. Wenns
es sich um eine C-Zeichenfolge handelt (NULL-terminiert), muss die Signatur der Methode nicht denlen
Parameter enthalten. Imo, wenn Sie die Länge als Argument übergeben, nehmen Sie an, dass das Array keine C-Zeichenfolge ist. Wenn Sie also keine C-Zeichenfolge an die Funktion übergeben, kann die Zeile zus[len] = 0
Unterbrechungen führen, da das Array von 0 auf len-1 wechselt. Und selbst wenn Sie eine C-Zeichenfolge an die Funktion übergeben, ist die Zeiles[len] = 0
redundant.Hier ist meine Anpassung der Antwort von Ates Goral mit C ++ 11. Ich habe das Lambda hier hinzugefügt, aber das Prinzip ist, dass Sie es weitergeben und dadurch steuern können, welche Zeichen Ihre Zeichenfolge enthält:
Hier ist ein Beispiel für die Übergabe eines Lambda an die Zufallszeichenfolgenfunktion: http://ideone.com/Ya8EKf
Warum sollten Sie C ++ 11 verwenden ?
Beispielsweise:
Beispielausgabe.
quelle
rand()
in Ihrem ersten Code-Snippet zu verwenden?rand()
. Es ist nicht einmal Uniform für lautes Schreien ...Meine 2p-Lösung:
quelle
default_random_engine
stattmt19937
? Der Code würde allgemeiner aussehen.std::default_random_engine
kann ich es nicht empfehlen, da der Standard keine Garantie für seine Qualität, Effizienz oder Wiederholbarkeit zwischen Implementierungen gibt.sizeof
, ändern Sie dasauto&
instd::string
, was Ihnenstd::string::length
std::string
wahrscheinlich langsamer ist, da es einen internen Zeiger auf seine Daten enthält. Dies würde eine zusätzliche Indirektion bedeuten, die ein statisches Array nicht benötigt. Auchsizeof
kann nie langsamer als ,std::string::size
weil es eine Kompilierung konstant.std::size
erst erschienenC++17
und es gibt immer noch viele Leute, die nur codieren,C++11/14
also werde ich es so lassen, wie es jetzt ist.quelle
Ich habe das gerade getestet, es funktioniert süß und erfordert keine Nachschlagetabelle. rand_alnum () verdrängt alphanumerische Zeichen, aber da 62 von 256 möglichen Zeichen ausgewählt werden, ist dies keine große Sache.
quelle
Verwenden Sie in diesem Fall lieber den entsprechenden C ++ - Algorithmus
std::generate_n
mit einem geeigneten Zufallszahlengenerator, als manuell zu schleifen :Dies kommt etwas nahe, das ich als "kanonische" Lösung für dieses Problem bezeichnen würde.
Leider ist es sehr schwierig , einen generischen C ++ - Zufallszahlengenerator (z. B. MT19937) richtig zu setzen . Der obige Code verwendet daher eine Hilfsfunktionsvorlage
random_generator
:Dies ist komplex und relativ ineffizient. Zum Glück wird es verwendet, um a zu initialisieren
thread_local
Variablen verwendet und daher nur einmal pro Thread aufgerufen.Schließlich sind die notwendigen Einschlüsse für die oben genannten:
Der obige Code verwendet die Ableitung von Klassenvorlagenargumenten und erfordert daher C ++ 17. Es kann für frühere Versionen trivial angepasst werden, indem die erforderlichen Vorlagenargumente hinzugefügt werden.
quelle
std::size_t
fürstd::uniform_int_distribution
? Ich kann kein anderes CTAD sehenrng
alstemplate <typename T = std::mt19937> inline thread_local T default_rng = get_random_generator<T>();
std::uniform_int_distribution<>
, was sicher wäre, aber vor signierter -> nicht signierter Konvertierung warnen könnte.Ich hoffe das hilft jemandem.
Getestet unter https://www.codechef.com/ide mit C ++ 4.9.2
Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd
quelle
RandomString(100)
! ;-)std::srand()
ist, dass es zu Beginn des Programms nur einmal aufgerufen werden sollte (vorzugsweise als erstesmain()
). Der Code generiert so wie er ist viele identische "zufällige" Zeichenfolgen, wenn er in einer engen Schleife aufgerufen wird.Hier ist ein lustiger Einzeiler. Benötigt ASCII.
quelle
quelle
std::string
anstelle vonstd::string::value_type[]
Noch einfacher und grundlegender, falls Sie sich freuen, dass Ihre Zeichenfolge druckbare Zeichen enthält:
quelle
Zufällige Zeichenfolge, jede Ausführungsdatei = andere Zeichenfolge
quelle
std::generate_n
davon ausgegangencustom_string
wirdLENGTH_NAME
, dass es eine Länge hat, dies jedoch nicht.Beispiel für Qt-Verwendung :)
quelle
Lassen Sie uns zufällig wieder bequem machen!
Ich habe eine schöne Lösung für C ++ 11-Header entwickelt. Sie können Ihrem Projekt problemlos eine Header-Datei hinzufügen und dann Ihre Tests hinzufügen oder zufällige Zeichenfolgen für andere Zwecke verwenden.
Das ist eine kurze Beschreibung, aber Sie können dem Link folgen, um den vollständigen Code zu überprüfen. Der Hauptteil der Lösung ist in der Klasse Randomer:
Randomer
fasst alle zufälligen Dinge zusammen und Sie können ganz einfach Ihre eigenen Funktionen hinzufügen. Nachdem wir habenRandomer
, ist es sehr einfach, Zeichenfolgen zu generieren:Schreiben Sie unten Ihre Verbesserungsvorschläge. https://gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad
quelle
Noch eine Anpassung, weil keine der Antworten meinen Bedürfnissen genügen würde. Wenn rand () zum Generieren von Zufallszahlen verwendet wird, erhalten Sie bei jedem Lauf die gleiche Ausgabe. Der Startwert für den Zufallszahlengenerator muss eine Art Zufallsgenerator sein. Mit C ++ 11 können Sie eine "zufällige" Bibliothek einbinden und den Startwert mit random_device und mt19937 initialisieren. Dieser Startwert wird vom Betriebssystem bereitgestellt und ist für uns zufällig genug (z. B. Uhr). Sie können einen Bereich angeben, in dem Grenzen [0,25] enthalten sind. Und zu guter Letzt brauchte ich nur zufällige Kleinbuchstaben, also benutzte ich die Zeichenaddition. Mit einem Pool von Charakteren hat der Ansatz für mich nicht geklappt.
quelle
Seien Sie vorsichtig, wenn Sie die Funktion aufrufen
(angepasst an @Ates Goral ) führt jedes Mal zur gleichen Zeichenfolge. Verwenden
vor dem Aufruf der Funktion, obwohl die Funktion rand () immer mit 1 @kjfletch gesetzt ist .
Beispielsweise:
quelle
quelle
quelle