我正在尝试生成具有以下两项的数据集:(i)包含从随机生成的值(0001到2000)的学生ID以及(ii)与学生ID(18到30)相对应的年龄。这些随机值保存在各自的数组[1000] 中,如代码
中所示我遇到了rand()的问题,我已经指定我要为1到2000的学生ID生成随机数,但我遇到了我认为是整数溢出的问题。我认为问题可能来自以下之一:
您可以在输出
中看到我遇到的问题代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int createDataSet(void)
{
srand(time(NULL)); // generates the random numbers
int i = 0, x, p, count;
char arrayId[1000]; // array that holds the ID's of 1000 students
char arrayAges[1000]; // array that holds the ages of 1000 students
for (count = 0; count < 1000; count++) // Init the "age" and "id" arrays
{
arrayId[count] = rand() % 2000 + 1; // ID range 0001 - 2000
arrayAges[count] = rand() % (30 + 1 - 18) + 18; // Age range 18 - 30
}
while(i<1000){
int r=rand() % (2000 + 1 - 0001) + 0001;
for (x = 0; x < i; x++)
{
if(arrayId[x]==r){
break;
}
}
if(x==i){
arrayId[i++]=r;
}
}
for (p = 0; p < 1000; p++)
{
printf("ID Number: %d Age: %d\n", arrayId[p], arrayAges[p]);
}
return 0;
}
输出:
ID Number: 115 Age: 28
ID Number: 104 Age: 21
ID Number: -113 Age: 25
ID Number: -3 Age: 18
ID Number: -41 Age: 20
ID Number: -94 Age: 28
ID Number: -4 Age: 19
ID Number: 4 Age: 28
ID Number: -112 Age: 23
ID Number: 33 Age: 20
ID Number: -119 Age: 30
ID Number: 12 Age: 23
ID Number: -96 Age: 27
ID Number: -88 Age: 30
ID Number: -105 Age: 20
我的目标是尝试获取数组中的值,如ID号中所示:显示1到2000之间的随机值,并且是无符号类型。任何帮助表示赞赏。谢谢你的时间!
答案 0 :(得分:1)
虽然您已经对尝试分配和char
到char
变量范围之外的整数值的初始问题有了一个很好的答案,但仍有大量小问题无法解决
首先,不要在代码中使用幻数。如果您需要常量,可以#define
或使用全局enum
来定义它们,例如
/* if you need a constants, define them */
enum { MINA = 18, MAXA = 30, MAXS = 1000, MAXID = 2000 };
(其中MINA
只是MINIMUMAGE
的缩写,MAXS
的{{1}}等等。)
这样,如果您需要更改范围或限制,您可以在代码顶部放置一个简单的位置来进行更改,而不必选择所有循环限制和变量声明。< / p>
接下来,MAXIMUMSTUDENTS
中的return 0;
毫无意义。如果您没有返回值,并且您没有在需要返回测量成功/失败的函数中执行任何操作,则将您的函数声明为createDataset
。同样,该函数可以生成数据集并将值打印到void
,但如果代码的其余部分需要数据集,则无法使用它。为什么?所有数组stdout
都被声明为函数的本地数据,并且当函数返回时,它们存储的内存将被销毁(释放以便重用)。您可能希望重构代码以在char arrayId[]..
中声明数组,并将数组以及元素数传递给函数进行初始化。
您可以在函数中使用此临时存储,以防止重复ID。您可以简单地声明一个main()
长度的字符数组(比如MAXID
),初始化为全零,并且在生成每个相应的ID时,将该索引处的值设置为char filled[MAXID] = "";
(或一些非零价值)。这使得重复检查成为1
当您考虑重构代码时,您希望将每个函数的功能分成逻辑单元。您的组合生成ID /年龄和输出可能符合您的直接需求,但考虑将生成函数和输出分离为单独的函数。
虽然不是错误,但C的标准编码样式避免使用if (filled[r]) { /* regenerate ID */ }
或camelCase
变量名来支持所有小写,同时保留用于宏和常量的大写名称。这是一个风格问题 - 所以它完全取决于你,但如果不遵循它可能会在某些圈子中产生错误的第一印象。
将这些部分组合在一起,您可以将当前函数重构为单独的生成和打印函数,如下所示:
MixedCase
注意: void createdataset (unsigned short *ids, char *ages, int count)
{
char filled[MAXID] = {0}; /* array preventing duplicates */
for (count = 0; count < MAXS; count++) /* for each student */
{
/* generate an ID */
unsigned short r = (unsigned short)(rand() % MAXID + 1);
while (filled[r]) /* while a duplicate, regenerate */
r = (unsigned short)(rand() % MAXID + 1);
filled[r] = 1; /* set filled[index] to 1 */
ids[count] = r; /* assign ID to student */
ages[count] = (char)(rand() % (MAXA - MINA + 1) + MINA);
}
}
void prndataset (unsigned short *ids, char *ages, int count)
{
int i = 0;
for (i = 0; i < count; i++)
printf ("ID Number: %4hu Age: %2hhd\n", ids[i], ages[i]);
}
只应在代码中调用一次。因此,如果您可能生成多个数据集,则应将其放在srand
中以确保仅调用一次。
当您开发必须符合特殊条件的代码时,例如main()
之间的ID和1-2000
之间的年龄,请考虑编写一个简单的验证检查,以验证您的所有值在范围内。例如,您可以执行以下操作:
18-30
(成功时会返回int validateset (unsigned short *ids, char *ages, int count)
{
int i = 0, err = 0;
for (i = 0; i < count; i++) {
if (ids[i] < 1 || ids[i] > MAXID) {
fprintf (stderr, "error: arrayid[%d] : %hu out of range.\n",
i, ids[i]);
err = 1;
}
if (ages[i] < MINA || ages[i] > MAXA) {
fprintf (stderr, "error: arrayages[%d] : %hhd out of range.\n",
i, ages[i]);
err = 1;
}
}
return err;
}
,如果在输出任何违规值后有任何值超出范围,则会0
此外,在打印值时,请确保格式说明符与要输出的值类型相匹配。虽然促销规则将使用1
或short
格式说明符处理将较小的值(例如int
)转换为%d
,但如果您的编译器支持%u
修饰符,它们应该用于指定正确的输出尺寸(例如打印h
,使用unsigned short
或打印%hu
,使用unsigned char
。
在一个简短的示例中将所有部分放在一起,您可以重构代码并添加一个类似于以下内容的验证检查:
%hhu
(通过添加验证检查,您可以放心,如果您的代码在没有显示错误的情况下运行,则数据集已正确生成)
示例使用/输出
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* if you need a constants, define them */
enum { MINA = 18, MAXA = 30, MAXS = 1000, MAXID = 2000 };
void createdataset (unsigned short *ids, char *ages, int count)
{
char filled[MAXID] = {0}; /* array preventing duplicates */
for (count = 0; count < MAXS; count++) /* for each student */
{
/* generate an ID */
unsigned short r = (unsigned short)(rand() % MAXID + 1);
while (filled[r]) /* while a duplicate, regenerate */
r = (unsigned short)(rand() % MAXID + 1);
filled[r] = 1; /* set filled[index] to 1 */
ids[count] = r; /* assign ID to student */
ages[count] = (char)(rand() % (MAXA - MINA + 1) + MINA);
}
}
void prndataset (unsigned short *ids, char *ages, int count)
{
int i = 0;
for (i = 0; i < count; i++)
printf ("ID Number: %4hu Age: %2hhd\n", ids[i], ages[i]);
}
int validateset (unsigned short *ids, char *ages, int count)
{
int i = 0, err = 0;
for (i = 0; i < count; i++) {
if (ids[i] < 1 || ids[i] > MAXID) {
fprintf (stderr, "error: arrayid[%d] : %hu out of range.\n",
i, ids[i]);
err = 1;
}
if (ages[i] < MINA || ages[i] > MAXA) {
fprintf (stderr, "error: arrayages[%d] : %hhd out of range.\n",
i, ages[i]);
err = 1;
}
}
return err;
}
int main (void) {
unsigned short arrayid[MAXS] = {0}; /* size your type to your needed */
char arrayages[MAXS] = {0}; /* range and enforce the range */
srand(time(NULL)); /* initialize random number seed */
createdataset (arrayid, arrayages, MAXS); /* initialize dataset */
if (validateset (arrayid, arrayages, MAXS)) /* validate dataset */
exit (EXIT_FAILURE);
prndataset (arrayid, arrayages, MAXS); /* output dataset */
return 0;
}
虽然您的主要问题是在$ ./bin/createdataset > dat/dataset1.txt
$ head -n 10 dat/dataset1.txt; echo "..."; tail -n 10 dat/dataset1.txt
ID Number: 1049 Age: 29
ID Number: 743 Age: 21
ID Number: 915 Age: 22
ID Number: 1539 Age: 19
ID Number: 793 Age: 18
ID Number: 1166 Age: 21
ID Number: 372 Age: 28
ID Number: 1763 Age: 19
ID Number: 782 Age: 20
ID Number: 1490 Age: 30
...
ID Number: 186 Age: 30
ID Number: 1389 Age: 23
ID Number: 1630 Age: 22
ID Number: 432 Age: 27
ID Number: 240 Age: 24
ID Number: 152 Age: 25
ID Number: 1598 Age: 22
ID Number: 1408 Age: 24
ID Number: 834 Age: 24
ID Number: 1699 Age: 25
问题中存储int
,但还有许多其他更微妙的问题需要考虑。仔细看看,如果您有任何其他问题,请告诉我。
答案 1 :(得分:0)
将arrayId[index]
声明为无符号短数组,因为255
在2000
只能存储unsigned short arrayId[1000]; /* try to store negative number, cyclic flow will happen */
unsigned char arrayAges[1000];
soup = BeautifulSoup(r.content,'xml')
updates = soup.findAll('body')
for update in updates:
if not "Next Steps" in update:
print (update)
else:
print "update good"
时不会起作用。但是你想要存储到<body>This is sentence one</body>
<body>This is sentence two. Next Steps: Find sentence three.</body>
<body>This is sentence three.
Next Steps:
Find sentence four.</body>
。
{{1}}
答案 2 :(得分:0)
使用此代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(NULL));
int i = 0, x, p, count;
unsigned arrayId[1000]; //You Can USE :unsigned int or unsigned short
char arrayAges[1000];
for (count = 0; count < 1000; count++)
{
arrayId[count] = rand() % 2000 + 1;
arrayAges[count] = rand() % (30 + 1 - 18) + 18;
}
for (p = 0; p < 1000; p++)
{
printf("%d.ID Number: %ld Age: %d\n",p+1, arrayId[p], arrayAges[p]);
}
return 0;
}
输出:
1.ID Number: 1467 Age: 27
2.ID Number: 1316 Age: 21
3.ID Number: 1213 Age: 19
4.ID Number: 171 Age: 29
5.ID Number: 661 Age: 21
6.ID Number: 297 Age: 27
7.ID Number: 853 Age: 23
8.ID Number: 67 Age: 29
9.ID Number: 500 Age: 20
10.ID Number: 274 Age: 24
11.ID Number: 821 Age: 25
12.ID Number: 355 Age: 19
13.ID Number: 1797 Age: 23
14.ID Number: 1036 Age: 30
15.ID Number: 1637 Age: 18
16.ID Number: 385 Age: 22
17.ID Number: 1574 Age: 24
18.ID Number: 1305 Age: 20
19.ID Number: 1658 Age: 24
20.ID Number: 794 Age: 29
21.ID Number: 1758 Age: 24
22.ID Number: 1239 Age: 27
23.ID Number: 989 Age: 30
24.ID Number: 1449 Age: 22
25.ID Number: 1390 Age: 26
26.ID Number: 1731 Age: 25
27.ID Number: 1465 Age: 26
28.ID Number: 792 Age: 20
29.ID Number: 1974 Age: 24
30.ID Number: 1674 Age: 23
31.ID Number: 533 Age: 19
32.ID Number: 1078 Age: 28
33.ID Number: 571 Age: 25
34.ID Number: 48 Age: 20
35.ID Number: 115 Age: 19
36.ID Number: 345 Age: 24
.
.
.
979.ID Number: 35 Age: 30
980.ID Number: 965 Age: 29
981.ID Number: 457 Age: 26
982.ID Number: 615 Age: 24
983.ID Number: 667 Age: 26
984.ID Number: 1381 Age: 19
985.ID Number: 1032 Age: 20
986.ID Number: 534 Age: 26
987.ID Number: 1372 Age: 27
988.ID Number: 1299 Age: 24
989.ID Number: 1463 Age: 24
990.ID Number: 880 Age: 18
991.ID Number: 1928 Age: 28
992.ID Number: 867 Age: 23
993.ID Number: 1580 Age: 29
994.ID Number: 917 Age: 18
995.ID Number: 237 Age: 28
996.ID Number: 384 Age: 19
997.ID Number: 356 Age: 20
998.ID Number: 327 Age: 27
999.ID Number: 1768 Age: 18
1000.ID Number: 148 Age: 27
Process returned 0 (0x0) execution time : 1.832 s
Press any key to continue.
它也会帮助你
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(NULL)); // generates the random numbers
int i = 0, x, p, count;
int arrayId[1000]; // array that holds the ID's of 1000 students
char arrayAges[1000]; // array that holds the ages of 1000 students
for (count = 0; count < 1000; count++) // Init the "age" and "id" arrays
{
//arrayId[count] = rand() % 2000 + 1; // ID range 0001 - 2000
arrayId[count] =rand() % (2000 + 1 - 1) + 1;
arrayAges[count] = rand() % (30 + 1 - 18) + 18; // Age range 18 - 30
}
while(i<1000){
int r=rand() % (2000 + 1 - 0001) + 0001;
for (x = 0; x < i; x++)
{
if(arrayId[x]==r){
break;
}
}
if(x==i){
arrayId[i++]=r;
}
}
for (p = 0; p < 1000; p++)
{
printf("%d.ID Number: %ld Age: %d\n",p+1, arrayId[p], arrayAges[p]);
}
return 0;
}