Je voudrais créer une chaîne aléatoire, composée de caractères alphanumériques. Je veux pouvoir spécifier la longueur de la chaîne.
Comment faire cela en C ++?
La réponse de Mehrdad Afshari ferait l'affaire, mais je l'ai trouvée un peu trop verbeuse pour cette tâche simple. Les tables de consultation peuvent parfois faire des merveilles:
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
est incorrecte. Sis
est une chaîne C (terminée par NULL), alors la signature de la méthode n'aurait pas à contenir lelen
paramètre. Imo, si vous passez la longueur comme argument, vous supposez que le tableau n'est pas une chaîne C. Ainsi, si vous ne passez pas de chaîne C à la fonction, la lignes[len] = 0
pourrait casser des choses, puisque le tableau passerait de 0 à len-1. Et même si vous passez une chaîne C à la fonction, la lignes[len] = 0
serait redondante.Voici mon adaptation de la réponse d'Ates Goral en utilisant C ++ 11. J'ai ajouté le lambda ici, mais le principe est que vous pouvez le transmettre et ainsi contrôler les caractères que contient votre chaîne:
Voici un exemple de passage d'un lambda à la fonction de chaîne aléatoire: http://ideone.com/Ya8EKf
Pourquoi utiliseriez-vous C ++ 11 ?
Par exemple:
Exemple de sortie.
la source
rand()
dans votre premier extrait de code?rand()
. Ce n'est même pas uniforme pour pleurer à haute voix ...Ma solution 2p:
la source
default_random_engine
place demt19937
? Le code aurait l'air plus générique.std::default_random_engine
n'est pas quelque chose que je recommande car la norme ne donne aucune garantie sur sa qualité, son efficacité ou sa répétabilité entre les implémentations.sizeof
, changez leauto&
enstd::string
, ce qui vous donnestd::string::length
std::string
était susceptible d'être plus lent car il contient un pointeur interne vers ses données. Cela signifierait une indirection supplémentaire dont un tableau statique n'a pas besoin. Aussisizeof
ne peut jamais être plus lent questd::string::size
parce qu'il s'agit d'une constante de temps de compilation.std::size
n'est pas apparu avantC++17
et il y a encore beaucoup de gens qui ne codent que pourC++11/14
donc je vais le laisser tel quel pour le moment.la source
Je viens de tester cela, cela fonctionne bien et ne nécessite pas de table de consultation. rand_alnum () élimine en quelque sorte les caractères alphanumériques, mais comme il sélectionne 62 caractères sur 256 possibles, ce n'est pas un gros problème.
la source
Plutôt que de boucler manuellement, préférez utiliser l' algorithme C ++ approprié , dans ce cas
std::generate_n
, avec un générateur de nombres aléatoires approprié :C'est proche de quelque chose que j'appellerais la solution «canonique» de ce problème.
Malheureusement, semer correctement un générateur de nombres aléatoires C ++ générique (par exemple MT19937) est vraiment difficile . Le code ci - dessus utilise donc un modèle de fonction d'aide,
random_generator
:C'est complexe et relativement inefficace. Heureusement, il est utilisé pour initialiser une
thread_local
variable et n'est donc appelé qu'une seule fois par thread.Enfin, les éléments nécessaires pour ce qui précède sont:
Le code ci-dessus utilise la déduction des arguments de modèle de classe et nécessite donc C ++ 17. Il peut être facilement adapté pour les versions antérieures en ajoutant les arguments de modèle requis.
la source
std::size_t
pourstd::uniform_int_distribution
? Je ne vois aucun autre CTADrng
comme paramètre par défaut, avec quelque chose commetemplate <typename T = std::mt19937> inline thread_local T default_rng = get_random_generator<T>();
std::uniform_int_distribution<>
, ce qui serait sûr, mais pourrais avertir d'une conversion signée -> non signée.J'espère que ça aidera quelqu'un.
Testé sur https://www.codechef.com/ide avec C ++ 4.9.2
Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd
la source
RandomString(100)
! ;-)std::srand()
ne doit être appelé qu'une seule fois au début du programme (de préférence la première chosemain()
). Le code, tel quel, générera beaucoup de chaînes "aléatoires" identiques s'il est appelé dans une boucle serrée.Voici un drôle de one-liner. Nécessite ASCII.
la source
la source
std::string
place destd::string::value_type[]
Quelque chose d'encore plus simple et plus basique au cas où vous seriez satisfait que votre chaîne contienne des caractères imprimables:
la source
Chaîne aléatoire, chaque fichier d'exécution = chaîne différente
la source
std::generate_n
il supposera que lacustom_string
longueur aLENGTH_NAME
, mais ce n'est pas le cas.Exemple d'utilisation de Qt :)
la source
Rendons à nouveau le hasard pratique!
J'ai créé une belle solution d'en-tête C ++ 11 uniquement. Vous pouvez facilement ajouter un fichier d'en-tête à votre projet, puis ajouter vos tests ou utiliser des chaînes aléatoires à d'autres fins.
C'est une description rapide, mais vous pouvez suivre le lien pour vérifier le code complet. La partie principale de la solution est dans la classe Randomer:
Randomer
incapsule tous les éléments aléatoires et vous pouvez y ajouter facilement vos propres fonctionnalités. Une fois que nous l'avons faitRandomer
, il est très facile de générer des chaînes:Écrivez vos suggestions d'amélioration ci-dessous. https://gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad
la source
Encore une autre adaptation car aucune des réponses ne suffirait à mes besoins. Tout d'abord, si rand () est utilisé pour générer des nombres aléatoires, vous obtiendrez la même sortie à chaque exécution. La graine du générateur de nombres aléatoires doit être une sorte d'aléatoire. Avec C ++ 11, vous pouvez inclure une bibliothèque "random" et vous pouvez initialiser la graine avec random_device et mt19937. Cette graine sera fournie par l'OS et elle sera assez aléatoire pour nous (par exemple: horloge). Vous pouvez donner une plage de limites sont incluses [0,25] dans mon cas. Et le dernier mais non le moindre, je n'avais besoin que d'une chaîne aléatoire de lettres minuscules, donc j'ai utilisé l'ajout de caractères. Avec une approche de groupe de personnages n'a pas fonctionné pour moi.
la source
la source
Soyez vigilant lors de l'appel de la fonction
(adapté de @Ates Goral ) il en résultera à chaque fois la même séquence de caractères. Utilisation
avant d'appeler la fonction, bien que la fonction rand () soit toujours amorcée avec 1 @kjfletch .
Par exemple:
la source
la source
la source