rand/srand gibt verfälschtes Ergebnis zurück

  • C++

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

    rand/srand gibt verfälschtes Ergebnis zurück

    Hallo.
    In meinem Code verwende ich eine QStringList wo ich mit count() size() auslesen kann, wieviele Elemente sich dortdrin befinden. Das klappt auch soweit so gut:

    C-Quellcode

    1. QStringList elements = load_playlist_elements("G:\\sample2.ini");
    2. int count = elements.size();

    Der Integer Count hat dann den Wert 4, dies ist auch korrekt.

    Nun habe ich eine kleine Funktion die mir einen Random Integer in einem bestimmten Bereich zurückgibt:

    C-Quellcode

    1. static int select_random(int max); // shuffle_algo
    2. int
    3. select_random(int max) {
    4. srand(time(NULL));
    5. return rand() % max;
    6. }


    Nun wenn ich jetzt versuche diese Funktion zu benutzen, und als Parameter count benutze welcher den Wert 4 beträgt bekomme ich ein komplett verfälschtes Ergebnis:

    C-Quellcode

    1. int count = elements.size();
    2. int rndm = select_random(count);


    Der Integer rndm beträgt den Wert 7143372 und nicht einen Wert zwischen 0 - 3. Wo ist hier der Denkfehler? Oder bin ich einfach blind? Folgendes proof-of-concept (im Anhang) funktioniert einwandfrei und benutzt die selbe Funktion. Ich hoffe mir kann damit jemand weiterhelfen. Danke schonmal im Vorraus :)

    "Der ganze Code"

    C-Quellcode

    1. #include "simpleini/SimpleIni.h"
    2. #include <QApplication>
    3. #include <QMainWindow>
    4. #include <QStringList>
    5. #include <QFile>
    6. #include <stdlib.h>
    7. #include <time.h>
    8. struct playlist_header {
    9. QString ph_name;
    10. QString ph_genre;
    11. QString ph_description;
    12. QString ph_sorting;
    13. };
    14. static playlist_header load_playlist_head(const char *playlist_file);
    15. static QStringList load_playlist_elements(const QString &playlist_file);
    16. static int select_random(int max); // shuffle_algo
    17. static int was_played(int list[], int rnd); // playlist_shuffle
    18. int
    19. main(int argc, char *argv[]) {
    20. QApplication app(argc, argv);
    21. QMainWindow window;
    22. #if 0
    23. CSimpleIniA window_opts;
    24. window_opts.SetUnicode();
    25. window_opts.LoadFile("G:\\sample.ini");
    26. const char *hVal = window_opts.GetValue("window", "title");
    27. QString wndwTitle = hVal;
    28. window.setWindowTitle(wndwTitle);
    29. window.show();
    30. window_opts.SetValue("window", "title", "Changed.");
    31. window_opts.SaveFile("G:\\sample.ini");
    32. #endif
    33. playlist_header _ph = load_playlist_head("G:\\sample2.ini");
    34. QStringList elements = load_playlist_elements("G:\\sample2.ini");
    35. int count = elements.size();
    36. int rndm = select_random(count);
    37. #if 0
    38. // try on your own warranty!
    39. playlist_header _ph = load_playlist_head("G:\\hardcore_sample.ini");
    40. QStringList elements = load_playlist_elements("G:\\hardcore_sample.ini");
    41. #endif
    42. window.setWindowTitle(_ph.ph_name + " " + _ph.ph_genre + " " + _ph.ph_sorting + " -- " + _ph.ph_description);
    43. window.show();
    44. return app.exec();
    45. }
    46. playlist_header
    47. load_playlist_head(const char *playlist_file) {
    48. playlist_header ph;
    49. CSimpleIniA _playlist_file;
    50. _playlist_file.SetUnicode();
    51. _playlist_file.LoadFile(playlist_file);
    52. ph.ph_name = _playlist_file.GetValue("playlist.head", "name");
    53. ph.ph_genre = _playlist_file.GetValue("playlist.head", "genre");
    54. ph.ph_description = _playlist_file.GetValue("playlist.head", "descr");
    55. ph.ph_sorting = _playlist_file.GetValue("playlist.head", "sort");
    56. return ph;
    57. }
    58. QStringList
    59. load_playlist_elements(const QString &playlist_file) {
    60. QStringList _elements;
    61. QFile q_playlist_file(playlist_file);
    62. if (q_playlist_file.open( QIODevice::ReadOnly )) {
    63. while (!q_playlist_file.atEnd()) {
    64. QString line = q_playlist_file.readLine();
    65. if (line.startsWith("playable")) {
    66. _elements.append(line);
    67. }
    68. }
    69. }
    70. QStringList elements;
    71. Q_FOREACH(QString _element, _elements) {
    72. QString _key("playable = ");
    73. int key_pos = _element.indexOf(_key);
    74. if (key_pos >= 0)
    75. elements.append(_element.mid(key_pos + _key.length()));
    76. }
    77. _elements.clear();
    78. return elements;
    79. }
    80. int
    81. select_random(int max) {
    82. srand(time(NULL));
    83. return rand() % max;
    84. }
    85. int
    86. was_played(int list[], int rnd) {
    87. }


    Grüße
    Jan
    Dateien
    • shuffle_rand.zip

      (163,66 kB, 106 mal heruntergeladen, zuletzt: )
    Software being "Done" is like lawn being "Mowed". (Jim Benson)
    Warum nutzt Du nicht einfach qrand ?
    Generell ist der <random>-Header auch interessant.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Naja viel unterschied ausser das rand/srand durch die jeweiligen Qt Alternativen ersetzt worden ist, ist da nicht. Wie gesagt das andere was ich oben angehängt habe funktioniert einwandfrei nur das es halt reines C++ (ohne Qt) ist.
    Software being "Done" is like lawn being "Mowed". (Jim Benson)
    Ich habe das mal hier mit einem kleinen Programm, das denselben Code nutzt (nicht Qt), getestet. Die Werte, die rauskommen, befinden sich zwischen 0 und 3.
    Ich habe absolut keine Ahnung, was da falsch ist, da ja auch keine Pointer o. ä. vorkommen. Das müsste eigentlich passen. Wo ermittelst/benutzt Du denn den Wert von rndm? Oder passiert das eben auch bei Deinem Test im Anhang?

    Davon abgesehen ist die Initialisierung von Deinem Random etwas suboptimal. Das sollte nicht immer in dieser Routine stattfinden, denn wenn Du die Funktion mehrmals aufrufst, dann kommen dieselben Werte heraus. ;)
    Heißt, das Seeden sollte fest außerhalb stattfinden.
    printf ist btw C, wie es mit rand ist, weiß ich aus dem Stegreif gar nicht. Aber zum Testen ist das natürlich egal.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Das im Anhang funktioniert einwandfrei deshalb wundert mich das so. Wie gesagt war nur eben zum testen um zu gucken was es ausgibt deshalb printf und co ;) Ich schau da morgen noch mal rein aber anscheinend liegt das ja dann auf der Seite von Qt. Danke trotzdem schonmal :)
    Software being "Done" is like lawn being "Mowed". (Jim Benson)
    Ah, drum. Dann vermute ich ganz stark, dass der Fehler irgendwo bei der Auswertung in Deinem Programm liegt.
    Drum wäre die Stelle interessant.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: