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 mainFü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_stringchar* 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 10Wie 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