Random - zahl, zufälliges generieren von Strings



  • Hallo!

    Ich möchte in meiner Methode einen zufälligen String erstellen, und habe sehr viel im internet über das Thema "random number" gelesen.

    Ich hatte das so verstanden, dass man neben der Funktion rand(), noch srand() aufrufen muss, damit die Funktion nicht immer die gleichen Zahlen zurückgibt, jedoch werden bei mir die gleichen zurückgegeben:

    char* generate_string(int length) {
        int i, random;
        srand(time(NULL));  //das sollte das erstellen von gleichen Zahlen verhindern?!
    
      char final_string[length];
      char letter;
    
    for (i = 0; i < length; i++) {
      random = rand()%4+1 ; //random zahl zwischen 1- 4
    
      if (random == 1) letter = 'a';
      if (random == 2) letter = 'b';
      if (random == 3) letter = 'c';
      if (random == 4) letter = 'd';
    
    strncat(final_string, &letter, 1);
    
    }
    
    return final_string;
    }
    

    Wenn ich diese Methode jetzt aus Main 2 mal aufrufe, kriege ich komplett den gleichen String :S? Was übersehe ich hier?!



  • srand(time(0)) muss an den anfang der main.
    denn time(0) liefert innerhalb einer sekunde dauernd die gleiche zahl.



  • tinchi schrieb:

    random = rand()%4+1 ; //random zahl zwischen 1- 4
      if (random == 1) letter = 'a';
      if (random == 2) letter = 'b';
      if (random == 3) letter = 'c';
      if (random == 4) letter = 'd';
    }
    
    letter = 'a'+rand()%4 ; //random zeichen zwischen 'a'-'d'
    }
    


  • Wielange probierst du eigentlich schon, C zu programmieren?
    Wieviele Hinweise hier aus dem Forum hast du berücksichtigt?
    Keine. Dein Code ist Schrott.
    Es ist auch keine Verbesserung in deinem Code zu erkennen, lasse das Programmieren sein.

    Schrott ist:
    - du verwendest VLA
    - du initialisierst final_string nicht (weil du faulerweise VLA verwendest)
    - du gibst nur lokal gültigen Speicher nach außen
    - du rufst srand mehrfach auf, statt nur einmal in main

    Für deine wenigen Zeilen ist das schon beachtlich viel Schrott.



  • Tja, mann mus halt irgendwie anfangen, oder wusstest du von Geburt an wie man C programmiert?
    Ich setzte mich wenigstens mit meinem Unwissen auseinander um es zu beheben. Da brauch ich keine "tollen Ratschläge" sondern ignorier dann einfach meine Posts und problem solved.



  • Tvv



  • strcat erwartet als Argumente zwei Nullterminierte char-Arrays (C-Strings).
    Das hast du bei beiden Argumenten nicht.

    Am Ende der Funktion sind deren lokalen Variablen nicht mehr gültig. Auch final_string
    Da das ein Array ist, gibst du nur den Zeiger auf den Anfang zurück. ((daher zeigt der auf nicht mehr gültigen Speicher)

    srand ist schon gekärt.

    Bleibt noch das komische if -Konstrukt.

    letter = 'a' + rand()%4 ; // erledigt das gleiche
    

    Mal abgesehen davon, dass du letter so nicht einsetzten kannst (wg strcat )
    Also kommt das gleich in final_string

    char* generate_string(char *final_string, int length) {
    // du bekommst genug Platz von der rufenden Funktion 
      for (i = 0; i < length???; i++) {
        final_string[i] = ...
      }
      final_string[i] = '\0'; //die Nullterminierung nicht vergessen
    
      return final_string;
    }
    

    Achte darauf, dass du nicht zuviel Zeichen rein schreibst. Die '\0' braucht schließlich auch noch Platz.
    Überlege*, was bei den ??? hin kommt.

    *nicht raten



  • DirkB schrieb:

    strcat erwartet als Argumente zwei Nullterminierte char-Arrays (C-Strings).
    Das hast du bei beiden Argumenten nicht.

    Oh danke für den Hinweis! Das hatte ich nicht beachtet, natürlich funktioniert dass dan nicht mit einem char was ich dran versuche anzuhängen.

    DirkB schrieb:

    Am Ende der Funktion sind deren lokalen Variablen nicht mehr gültig. Auch final_string
    Da das ein Array ist, gibst du nur den Zeiger auf den Anfang zurück. ((daher zeigt der auf nicht mehr gültigen Speicher)

    Ja klar... das ist echt n anfängerfehler den ich da übersehen habe, danke!

    DirkB schrieb:

    letter = 'a' + rand()%4 ; // erledigt das gleiche
    

    Das hatte ich so gemacht, weil in meinem richtigen Programm andere Buchstaben genommen werden, also die nicht nacheinanderfolgend sind, aber wusste trotzdem nicht, dass man ints auf chars hinzufügen kann, danke für den Hinweis.

    DirkB schrieb:

    char* generate_string(char *final_string, int length) {
    // du bekommst genug Platz von der rufenden Funktion 
      for (i = 0; i < length???; i++) {
        final_string[i] = ...
      }
      final_string[i] = '\0'; //die Nullterminierung nicht vergessen
     
      return final_string;
    }
    

    Achte darauf, dass du nicht zuviel Zeichen rein schreibst. Die '\0' braucht schließlich auch noch Platz.
    Überlege*, was bei den ??? hin kommt.

    *nicht raten

    Hmmm ich glaube ich weiss nicht worauf du genau hinaus willst, obwohl ich glaube, meine Lücken von vorhin verstanden zu haben.

    int main(int argc, char** argv) {
    
    int length = 10; //moechte also einen String der länge 10
    char *final_string = malloc(sizeof(char) * (length+1)); //also 1 mehr wegen dem terminal symbol
    
    //koennte ich hier jetzt nicht theoretisch die Methode auf void ändern und einfach die übergebende Referenz des strings füllen?
    
    generate_string(final_string, length+1);
    
    free(final_string);
    }
    
    void generate_string(char* final_string, int length) {
    
    //[...] lasse das meiste weg da es gleich ist
    
    for(i = 0; i < length; i++) {....}
    // hier wuerde doch alles perfekt passen, der string würde bis zur position 10 gefüllt werden mit chars und dann mit dem:
    
    final_string[i] = '\0'; //terminiert, also an der stelle final_string[11]
    //deswegen verstehe ich deine "???" nicht :S, was übersehe ich denn wieder
    }
    


  • tinchi schrieb:

    Das hatte ich so gemacht, weil in meinem richtigen Programm andere Buchstaben genommen werden, also die nicht nacheinanderfolgend sind,

    Dann mach ein Array und nimm die Zufallszahl als Index.

    char Code[] = "abcd";
    ...
    letter = Code[rand()%4] ;
    

    Du musst auch mit deinen Indizes aufpassen.

    tinchi schrieb:

    int length = 10; //moechte also einen String der länge 10
    char *final_string = malloc(sizeof(char) * (length+1)); //also 1 mehr wegen dem terminal symbol
    ...
    for(i = 0; i < length; i++) {....}
    // hier wuerde doch alles perfekt passen, der string würde bis zur position 10 gefüllt werden mit chars und dann mit dem:
    
    final_string[i ] = '\0'; //terminiert, also an der stelle final_string[11]
    //deswegen verstehe ich deine "???" nicht :S, was übersehe ich denn wieder
    }
    

    Am Ende der for-Schleife steht i bei 10 und nicht bei 11.
    Es wird das 11. Element mit '\0' beschrieben, aber das ist an der Position 10

    Wie und wo du das +1 oder -1 (für die ???) hängt von deiner Definition ab.
    Du hast jetzt definiert, dass du die Anzahl der Zeichen (und nicht die Länge des Speicherbereichs) übergeben willst. Das ist ok.
    Aber da ist der Name length für den zweiten Parameter etwas irreführend.



  • tinchi schrieb:

    generate_string(final_string, length+1);
    

    Es wird length+1 übergeben, somit ist i am Ende 11 -> und das 12te Element(11te pos) wird mit NULL beschrieben und das liegt außerhalb des Speicherbereichs!!



  • DirkB schrieb:

    [...]
    Wie und wo du das +1 oder -1 (für die ???) hängt von deiner Definition ab.
    Du hast jetzt definiert, dass du die Anzahl der Zeichen (und nicht die Länge des Speicherbereichs) übergeben willst. Das ist ok.
    Aber da ist der Name length für den zweiten Parameter etwas irreführend.

    Ja da hast du recht, der Name ist etwas irreführend. Aber ich habe deine Hinweise alle verstanden also vielen Dank für die Zeit und Erklärung. Das mit arrays-strings und den ganzen Funktionen drum herum ist etwas klarer. Danke sehr


Anmelden zum Antworten