I’ve written some code to generate an array of structures. The id variable is intended to be unique and generated randomly. However, what seems to be happening is that if the generate function (which gnerates and fills the array of structures) encounters a matching number in the array, the flag variable is set to 0 and it exits the do loop without create a new random number to recheck for a match. Then when the loop exits, the code goes ahead and assigns the matching random number to the empty spot in the array anyway. As a caveat, I realize it would be simpler to just take all 10 possible integers, move them around, and fill the array, but I’m trying to get the hang of rand() using a small sample so I can watch what it’s doing in debugger. I suspect I’ve just been staring at this too long and tried too many things, but any suggestions would be appreciated. Thanks.
EDIT: Just to clarify my question specifically concerns the do loop and what I need to do to make sure that when a match is found, the program generates a new random number and begins searching again for a match. This should be repeated for each position in the array until each id element is unique. Currently, when I run the program, I’m still getting duplicate numbers.
#include <stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<assert.h>
struct student{
int id;
int score;
};
struct student* allocate(){
/*Allocate memory for ten students*/
struct student* s = malloc(10 * sizeof(struct student));
assert (s != 0);
/*return the pointer*/
return s;
}
void generate(struct student* students){
/*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
int i, j;
int flag;
int randNum = 0;
for (i = 0; i < 10; i++) {
flag = 1;
do {
randNum = (rand()%10 + 1); //generate random ID for each student
for (j = 0; j < 10 && flag == 1; j++) { //search array for matching numbers
if (students[j].id == randNum) {
flag = 0;
}
if (j == 9 && flag == 1) {
flag = 0;
}
}
}
while (flag == 1); //set condition
students[i].id = randNum;
students[i].score = (rand()%(100 - 0 + 1) + 0); //generate random score for each student
}
}
void output(struct student* students){
/*Output information about the ten students in the format:
ID1 Score1
ID2 score2
ID3 score3
...
ID10 score10*/
int i;
printf("Student scores: \n\n");
for (i = 0; i < 10; i++) {
printf("\t%d, %d\n", students[i].id, students[i].score);
}
}
void summary(struct student* students){
/*Compute and print the minimum, maximum and average scores of the ten students*/
int sumS, minS, maxS, avgS, i, j, tempID, tempS;
printf("Sorted students by scores: \n");
for (i = 0; i < 10; i++) {
sumS += students[i].score;
for (j = 0; j <10; j++) {
if (students[i].score < students[j].score) {
tempS = students[j].score;
tempID = students[j].id;
students[j].score = students[i].score;
students[j].id = students[i].id;
students[i].score = tempS;
students[i].id = tempID;
}
}
}
for (i = 0; i < 10; i++) {
printf("\t%d, %d\n", students[i].id, students[i].score);
}
printf("Minimum score: %d\n", minS = students[0].score);
printf("Maximum score: %d\n", maxS = students[9].score);
printf("Average score: %d", avgS = sumS/10);
}
void deallocate(struct student* stud){
/*Deallocate memory from stud*/
free(stud);
}
int main(){
struct student* stud = NULL;
/*call allocate*/
stud = allocate();
/*call generate*/
generate(stud);
/*call output*/
output(stud);
/*call summary*/
summary(stud);
/*call deallocate*/
deallocate(stud);
return 0;
}
You set the flag to
0if the number already was chosen, so you should testwhile(flag == 0), and re-set the flag to1at the start of the loop:Now,
flag == 0means “already seen, try again” andflag == 1means “it’s a new number, go ahead and write it to the array”.Also, you only have the array slots for indices
< ifilled, so the comparison loop should not go to9, but only toi-1.