我试图生成随机句子,但有时我会收到错误或打印随机字符。 以下是我的所作所为。 (句子应具有以下格式:文章,名词,动词,介词,文章和名词)。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
int main() {
srand(time(NULL));
int r1, r2, r3, r4, r5, r6;
char *article[] = {"the" , "a" , "one" , "some", "any"};
char *noun[] = {"boy" , "girl" , "dog" , "town", "car"};
char *verb[] = {"drove" , "jumped" , "ran" , "walked", "skipped"};
char *preposition[] = {"to" , "from" , "over" , "under", "on"};
r1 = rand() % 6; r2 = rand() % 6; r3 = rand() % 6; r4 = rand() % 6; r5 = rand() % 6; r6 = rand() % 6;
printf("%s %s %s %s %s %s\n", article[r1], noun[r2], verb[r3], preposition[r4], article[r5], noun[r6]);
return 0;
}
答案 0 :(得分:5)
r1 = rand() % 6;
有值0,1,2,3,4,5
但是第一个数组有5
个元素。因此,您正在访问数组索引超出范围并且具有未定义的行为。
相反
r1 = rand() % arraysize;
这样做。(同样你也需要为其他数组做。)
例如,在第一种情况下arraysize = 5
所以r1= rand()%5
和r2=rand()%5
等等。(这里所有数组的数组大小= 5)。
在这种情况下获取数组大小
r2 = rand()%( sizeof noun/ sizeof noun[0] );
答案 1 :(得分:1)
所有列表中的元素少于6个,因此随机例程会不时返回列表边界之外的值:读取垃圾指针=&gt;未定义的行为。所以现在&#34;随机&#34; bug被解释了。
现在,当您(或其他开发人员)向一个列表添加或删除元素时会发生什么?你必须再次调整尺寸。
我要创建一个小宏来避免这样做:
#define RANDSTRING(s) s[rand() % (sizeof(s)/sizeof(*(s)))]
现在:
const char *r = RANDSTRING(noun);
在noun
列表中选择一个值,保证在边界内。
它适用于字符串列表并正确计算大小。尽管如此,它还是不会使用像char **
这样的指针。
它也不适用于空列表(% 0
是非法的,无论如何都没有意义)