虽然对于尝试将 char 范围之外的整数值分配给 char 变量的初始问题,您已经有了一个很好的答案,但仍有大量小问题尚未解决。
首先,不要在代码中使用幻数。如果您需要常量,可以使用#define 或使用全局enum 来定义它们,例如
/* if you need a constants, define them */
enum { MINA = 18, MAXA = 30, MAXS = 1000, MAXID = 2000 };
(其中MINA 是MINIMUMAGE 的缩写,MAXS 是MAXIMUMSTUDENTS 的缩写等)
这样,如果您需要更改范围或限制,您可以在代码顶部有一个简单的位置来进行更改,而不必挑选所有循环限制和变量声明。
接下来,createDataset 中的 return 0; 毫无意义。如果你没有要返回的值,并且你没有在函数中做任何需要返回来衡量成功/失败的事情,那么将你的函数声明为void。同样,该函数可能会生成一个数据集并将值打印到stdout,但如果您的代码的其余部分需要该数据集,则无法使用它。为什么?您的所有数组 char arrayId[].. 都声明为函数的本地,并且当函数返回时,它们存储的内存将被销毁(释放以供重用)。您可能需要重构代码以在 main() 中声明数组并将数组以及元素数量传递给您的函数以进行初始化。
您可以在函数中使用此临时存储来防止重复 ID。您可以简单地声明一个长度为MAXID 的字符数组(例如char filled[MAXID] = "";),初始化为全零,并在生成每个相应的ID 时,将该索引处的值设置为1(或某个非零值)。这使得重复检查成为if (filled[r]) { /* regenerate ID */ }的简单测试
当您考虑重构代码时,您希望将每个函数的功能分成逻辑单元。您的组合生成 ID/年龄和输出可能适合您的直接需求,但请考虑将生成函数和输出分离为单独的函数。
虽然不是错误,但 C 的标准编码风格避免使用 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)
此外,当您打印值时,请确保您的格式说明符与您输出的值的类型相匹配。虽然提升规则将使用%d 或%u 格式说明符处理将较小的值(例如short)转换为int,但如果您的编译器支持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
虽然您的主要问题是在char 问题中存储int,但还有许多其他更微妙的问题需要考虑。如果您有任何其他问题,请查看并告诉我。