我正在嘗試使用以下代碼創建一個隨機字串生成器。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Random string generator
void rand_str(char *dest, size_t length) {
char charset[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int charset_length = 62;
while (length-- > 0) {
size_t index = rand() % charset_length;
*dest = charset[index];
}
*dest = '\0';
}
int main ()
{
int num_data = 5;
int string_length;
int max_string_length = 10;
char data[num_data][string_length];
int i = 0;
while (i < num_data)
{
string_length = 3 (rand() % max_string_length);
char str[string_length];
rand_str(str, string_length);
short increment_avoider_flag = 0;
for (int j = 0; j < i; j )
{
if (!strcmp(data[j], str))
{
string_length = 3 (rand() % max_string_length);
char str[string_length];
rand_str(str, string_length);
increment_avoider_flag = -1;
break;
}
}
if (!increment_avoider_flag)
{
memcpy(data[i], str, sizeof(str));
printf("%s\n", str);
printf("%s\n\n\n", data[i]);
i ;
}
}
}
上述代碼的輸出是
pn2QMwQbLq
pn2QMwQbLq~??
WqJ99NSq
WqJ99NSqLq~??
LDvi5z
LDvi5zSqLq~??
gxBewrk5rHr
gxBewrk5rHr??
DcDg
DcDgwrk5rHr??
這里的輸出有兩個問題。
- 如果創建的第一個字串的長度 x 大于后面的字串長度,則 memcpy 也會復制前一個字串的殘差。例如,第一個字串是
pn2QMwQbLq,第二個字串是WqJ99NSq,但復制的字串是第一個字串WqJ99NSqLq~??的附加Lq字串。 - 復制的 stings 中有一些垃圾字符。例如,第一個原始字串
pn2QMwQbLq但復制的字串pn2QMwQbLq~??有額外~??的 .
我不確定這里發生了什么,但似乎我錯誤地宣告或復制了字符陣列。請幫我解決這個問題。
uj5u.com熱心網友回復:
如果要生成沒有任何記憶體泄漏的隨機字串。
下面的代碼實作了某種map時間復雜度為 的結構O(n),其中 n 是字串的長度。這不是一個好的實作map,但是在 C 中創建 amap將是一項繁重的任務。
優點:
- 沒有堆記憶體分配
- 最終隨機字串中沒有重復字符
缺點:
- 不是一個好的實作
map,因為時間復雜度應該是O(log(n))
這里在線試一下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
const char *charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
void random_str(char *str, size_t len);
void random_str(char *str, size_t len)
{
if (len == 0)
{
fprintf(stderr, "could not generate 0 length string\n");
exit(1);
}
for (size_t i = 0; i < len; i )
{
str[i] = charset[(rand() % 62)];
}
str[len] = 0;
}
#define MAX_LEN 10
int main(void)
{
char rdata[MAX_LEN][MAX_LEN 1] = {0};
srand(time(NULL));
for (size_t i = 0; i < 10;)
{
int flag = 1;
random_str(rdata[i], 10);
for (size_t j = 0; j < i; j )
if (strcmp(rdata[i], rdata[j]) == 0)
flag = 0;
if (flag == 1)
{
printf("%s\n", rdata[i]);
i ;
}
}
return 0;
}
uj5u.com熱心網友回復:
您的代碼中有多個問題:
定義
char data[num_data][string_length];具有未定義的行為,因為string_length未初始化。您應該使用char data[num_data][max_string_length 1];允許空終止符。3 (rand() % max_string_length)3在to范圍內產生一個偽隨機整數max_string_length 2,這似乎是不正確的。您應該使用以包含范圍來3 (rand() % (max_string_length - 2)獲取范圍。3max_string_lengthchar str[string_length];定義一個位元組的陣列str對于一串字符來說太短了string_length。如果發生沖突,則無需生成新的隨機字串,尤其是在新的本地陣列中。只需設定指標并從回圈中中斷。
您可以通過在回圈
j外部定義并使用來檢查是否沒有重復項來消除對指標的需求。fori == j您應該為亂數生成器播種,以避免在每次運行時生成相同的字串。采用
srand(time(NULL));
多次出現未定義的行為來解釋意外結果。
這是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// Random string generator
void rand_str(char *dest, size_t length) {
static const char charset[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int charset_length = sizeof(charset) - 1;
while (length-- > 0) {
size_t index = rand() % charset_length;
*dest = charset[index];
}
*dest = '\0';
}
int main() {
int num_data = 5;
int max_string_length = 10;
char data[num_data][max_string_length 1];
int i = 0, j;
srand(time(NULL));
while (i < num_data) {
int string_length = 3 (rand() % (max_string_length - 2));
char str[string_length 1];
rand_str(str, string_length);
for (j = 0; j < i; j ) {
if (!strcmp(data[j], str))
break;
}
if (j == i) {
strcpy(data[i], str);
printf("%s\n", str);
i ;
}
}
printf("\n");
for (i = 0; i < num_data; i ) {
printf("%s\n", data[i]);
}
return 0;
}
uj5u.com熱心網友回復:
由于字串長度每次都在變化,因此您需要動態定義它,以下是對代碼的 2 處更改。
int main ()
{
int num_data = 5;
int string_length;
int max_string_length = 10;
//char data[num_data][string_length];
char **data = (char **)malloc(num_data * sizeof(char *)); //change1
int i = 0;
while (i < num_data)
{
string_length = 3 (rand() % max_string_length);
data[i] = (char*)malloc(string_length * sizeof(char)); //change2
char str[string_length];
rand_str(str, string_length);
short increment_avoider_flag = 0;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/429472.html
