Generating Unique Random Numbers in an Array using Loop - c

So the question is to develop a [5][5] table, each containing unique numbers from 1-100 (no duplicates)
so here's what I came up with:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int outerLoop;
int innerLoop;
int board[5][5]; /* Array Name And Size*/
/* seeds the random number generator*/
srand(time(NULL));
int number;
number = rand() % 101;
/* Start a loop to generate a random integer between 1 and 100 and
assign it into the array. The loop runs 25 times*/
for ( outerLoop = 0 ; outerLoop <= 25 ; outerLoop++ ) /* loop 25 times*/
{
for ( innerLoop = 0 ; innerLoop <= 4 ; innerLoop++ ) /* <=4 due to 5
columns*/
{
board[outerLoop][innerLoop] = rand() % 100 + 1;
}
printf( "%d \n", board[outerLoop][innerLoop] );
}
So I pretty much got stuck here.I'm not really sure about this:
board[outerLoop][innerLoop] = rand() % 100 + 1;
I simply made it up :/ Any idea guys?

What you want is a shuffle algorithm
Shuffle array in C
To get your 25 element array of unique #s from 1 to 100; just create a 100 element array with the numbers 1..100, shuffle the 1st 25 from the pool of 100, and use the 1st 25.
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
void shuffle(int *array, size_t array_size, size_t shuff_size)
{
if (array_size > 1)
{
size_t i;
for (i = 0; i < shuff_size - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (array_size - i) + 1);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
int main(int argc, char * argv[]) {
int a[100];
int b[5][5];
int i,j,k=0;
for(i=0; i<100;++i)
a[i]=i;
shuffle(a,100,25);
for(i=0;i<5;++i)
for(j=0;j<5;++j) {
b[i][j] = a[k++];
printf("%d ",b[i][j]);
}
printf("\n");
}
$ gcc -o test test.c
$ ./test
0 14 76 47 55 25 10 70 7 94 44 57 85 16 18 60 72 17 49 24 53 75 67 9 19

Think of it like a deck of 100 cards.
Create a 100 element array holding the card numbers (1..100)
Shuffle the array (=deck). (see #koodawg's answer and #Steve314's comment)
"Deal" yourself the first 25 cards off the deck, into your 5x5 array.

Just create array of boolean of size 100 : bool numberUsed[100]. Then in cycle:
1.Generate random number r
2.If numberUsed[r] is true, dont add that r anywhere and continue in loop
3.numberUsed[r] = true
Note that you need to use WHILE cycle with this approach, not FOR cycle.

Here is some pseudo code to solve it:
Create a "list" of length 100 containing the numbers 1...100 called "numbersAvailable"
In your inner loop set index = (int)rand() * numbersAvailable; and the take the number numbersAvailable.get(index); and then do numbersAvailable.remove(index);
In Java creating a list is easy. If you like to stick to C you have to emulate this via arrays. (I can write down the solution, but this looks like a homework, so I leave something for you).
Note: In contrast to a trial-and-reject solution, this solution has the advantage of a fixed amount of time needed to construct the result.

Since int board[5][5]; allocates a continuous amount of memory you can initialise it with just
for (i = 0; i < sizeof(board)/sizeof(int); i++)
board[0][i] = rand() % 100 + 1;
Or use a double loop like you did, but then you only need to loop 5 times in the other loop, or use sizeof to set the iteration count automatically:
for ( outerLoop = 0 ; outerLoop < sizeof(board)/sizeof(board[0]) ; outerLoop++ ) {
for ( innerLoop = 0 ; innerLoop < sizeof(board[0])/sizeof(board[0][0]) ; innerLoop++ ) {
board[outerLoop][innerLoop] = rand() % 100 + 1;
}
}
Please keep in mind that sizeof will only work on arrays in this way when the length of the array is known at compile time like it is in your example.

C stores arrays in row-major order, i.e, the elements of row 0 comes first , followed by the elements of row 1, and so forth.
We can take advantage of this by viewing int board[5][5] as int board[5*5].
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 5
int main()
{
int i, outerLoop = 1;
int board[N*N];
srand(time(NULL));
int number;
board[0] = rand() % 100 + 1; //initializing the first element
while(1)
{
number = rand() % 100 + 1 ;
if(outerLoop == N*N)
break;
else
{
//Cheking the previous elements for no duplicacy
for ( i = 0; i < outerLoop; i++)
{
if(number == board[i])
break;
}
//confirming whether all the elements are checked or not and the assigning number to the array element and then increment the counter outerLoop
if(i == outerLoop)
{
board[outerLoop] = number;
outerLoop++;
}
else
continue;
}
}
//Printing the elements of array board[N*N]
for ( outerLoop = 0 ; outerLoop < N*N ; outerLoop++ )
{
printf( "%d\t", board[outerLoop] );
if(outerLoop % N == 4)
printf("\n\n");
}
}

Related

How can I use the rand() function to generate a different number that hasn't been generated before?

// What I mean by this is shown by my example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int i;
int a;
for (a = 0;a <10;a ++) {
i = (rand()%10)+1; // generates a number from 1-10
printf("%d\n", i);
}
// I would like for the loop to generate a number that gives a number that was not generated before. For example, an output such as:
1,3,6,2,8,9,4,10,5,7
instead of:
3,9,10,3,7,9,2,7,10,1
In other words, I would like no copies.
You obviously don't just want no copies, but you want every number in a given set exactly once. This is, as commented by Robert, similar to shuffling a deck of cards. You don't have "decks" in C, but you can model one as an array:
int deck[] = {1,1,1,1,1,1,1,1,1,1};
This should represent 10 different "cards" (identified by their index in the array), each available one time. Now, just write code that "draws" cards:
int i = 0; // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n) // how many cards are left
{
int skip = rand() % n; // randomly skip 0 .. n cards
while (1)
{
if (deck[i]) // card still available?
{
if (!skip) break; // none more to skip -> done
--skip; // else one less to skip
}
if (++i > 9) i = 0; // advance index, wrapping around to 0
}
deck[i] = 0; // draw the card
printf("%d\n", i+1); // and print it out
}
of course, seed the PRNG (e.g. srand(time(0))) first, so you don't get the same sequence every time.
The idea shown in the question is to print numbers within a range, without repetition. Here is one way to do that, by putting each value into an array and swapping its elements around.
A variation could be that you don't want to use all the possible numbers, in that case just change PICKED.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRLEN 10
#define PICKED 10
int main(void) {
int array[ARRLEN];
srand((unsigned)time(NULL)); // seed the PRNG
for(int i = 0; i < ARRLEN; i++) { // generate the numbers
array[i] = i + 1;
}
for(int i = 0; i < ARRLEN; i++) { // shuffle the array
int index = rand() % ARRLEN;
int temp = array[i];
array[i] = array[index]; // by randomly swapping
array[index] = temp;
}
for(int i = 0; i < PICKED; i++) { // output the numbers
printf("%d ", array[i]);
}
printf("\n");
}
Program output:
9 8 4 5 1 10 7 3 6 2
The library's PRNG is not very random, but for many cases that is not important. If it is, better algorithms are available.

How do I print out 100 numbers in an array then add them using C

I'm trying to print out 100 numbers from an array using a loop and then add them all together. So far I have:
#include <stdio.h>
#include <stdlib.h>
int main(){
int* number = malloc(101 * sizeof(int));
int num = 0;
number[num] = 1;
while (number[num] <= 100){
printf(" %d\n ", number[num]);
num = num +1;
number[num] = number[num]+1;
}
return 0;
}
but this just prints 1 once.
number[num] = number[num]+1;
You only properly set number[0]. Now you are trying to take whats in number[1] and add to it, in the first iteration. You didn't set it to anything though, leaving it uninitialised. This is undefined behaviour. What you most likely wanted to do is
number[num] = number[num-1]+1;
To add one to the previous number before after printing it. Now it will print fine.
To add them up, simply do
for (int a = 0; a < 100; a++) {
number[100] += number[a]; // add number[a] to result
}
printf("%d\n",number[100]);
Also, don't forget to free your dynamically allocated array at the end.
Try this:
#include <stdio.h>
int main () {
int n[ 100 ]; /* n is an array of 100 integers */
int i,j;
int sum = 0;
/* initialization */
for ( i = 0; i < 100; i++ ) {
n[ i ] = i + 100; /* set element at location i to i + 100 */
}
/* output each array element's value */
for (j = 0; j < 100; j++ ) {
printf("Element[%d] = %d\n", j, n[j]);
sum += n[j];
}
printf("Sum of Elements = %d\n", sum);
return 0;
}
Remember that you should declare an array, then initialize it, print it out and after all print out the sum
You can just print out 1 to 100, then you could quickly use some maths to get the count of all numbers added together, for example, one of Gauss' algorithms, specifically http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/
There’s a popular story that Gauss, mathematician extraordinaire, had a lazy teacher. The so-called educator wanted to keep the kids busy so he could take a nap; he asked the class to add the numbers 1 to 100.
Here's what I would do: -
int i = 0;
for (i = 1; i <= 100; i++) {
printf("%d", i);
}
// gauss technique 100(100 + 1) / 2
int count = (100 * 100 + 100 * 1) / 2;
printf("all numbers added: %d", count);

Getting incorrect output when I implement merge sort with threads, can't figure out what's wrong

I've been at this problem for like 3 days and I've combed my entire code to try to figure out why I'm getting incorrect output. The purpose of this program is to do a merge sort using threads. The first part is simply sorting the elements in parallel into however many segments a user inputs. The only inputs tested will be 2, 5, and 10. And the array to be sorted will always be 50 int array of randomly generated numbers.My code works fine when the segments entered (denoted by the variable 'segments' at the top of main) is 2. However, when I change segments to 5 or 10, I don't get a sorted array at the end. I've tried debugging by using print statements (which I've commented out but you can still see) and there seems to be a problem during the first two merge iterations. For some reason the resulting of those merge iterations are not in order, and they contain duplicate numbers that don't exist in duplicate in the original array passed to it. My sorting method and merging methods work fine when I just pass arrays to them, and don't use threads but when I do use threads I get behavior that I can't explain. Below is my program in its entirety, to merge an array of 50 it should do the following:
split the array into 10 segments of 5, and sort each segment.
pass the segments in pairs, in rounds. So round one should pas segment 0-5 in one segment and 5-10 in another, 10-15 and 15-20, 20-25 and 25-30, and so on until it reaches 40-45 and 45-50.
then it will go into round two which does same thing as round one but it passes the segments in pairs of 10. So 0-10 and 10-20, 20-30 and 30-40, then it leaves the last part of 10 untouched
round three passes the segments to merge in pairs of 20: 0-20 and 20-40, then stops.
Finally it should merge the segments 0-40 with 40-50.
My program: (you should mainly focus on my main function, sort is fine, and merge seems fine too, but i've included them anyways just in case)
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
/**
* Struct to contain an array partition as well as the size of the partition.
* Use struct to pass multiple parameters to pthread_create
*/
struct array_struct{
int *partition;
int size;
};
/**
* Struct that contains two arrays (should be sorted) to merge
* Use struct to pass multiple parameters to pthread_create
*/
struct arrays_to_merge{
int *array1;
int *array2;
int size1;
int size2;
};
//comparison function to use with qsort, sorts in ascending order
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
/**
* Method that takes a struct containing a pointer to the first int in an array
* partition, as well as the partition size. Object must be type void, used with pthread_create
* #param pointer to the partition object. Type void
*/
void *sort(void *object){
struct array_struct *structure;
structure = (struct array_struct *) object;
int *array = structure->partition;
int size = structure->size;
int *i, j = 0;
qsort(array, size, sizeof(int), cmpfunc);
printf("Sorted %d elements.\n", size);
}
void *merge(void * object){
struct arrays_to_merge *arrays_struct;
arrays_struct = (struct arrays_to_merge *) object;
int *array1 = arrays_struct->array1;
int *array2 = arrays_struct->array2;
int size1 = arrays_struct->size1;
int size2 = arrays_struct->size2;
int tempArray[size1 + size2];
int i = 0, j = 0, k = 0, duplicates = 0;
while (i < size1 && j < size2) {
// printf("Merge number : %d Comparing %d and %d\n", mergenumber, array1[i], array2[j]);
if (array1[i] <= array2[j]) {
// printf("Picking %d\n", array1[i]);
tempArray[k] = array1[i];
if (array1[i] == array2[j])
{
duplicates++;
}
i++;
k++;
}else {
// printf("Merge number : %d Picking %d\n", mergenumber, array2[j]);
tempArray[k] = array2[j];
k++;
j++;
}
}
while (i < size1) {
// printf("Merge number : %d left over Picking %d\n", mergenumber, array1[i]);
tempArray[k] = array1[i];
i++;
k++;
}
while (j < size2) {
// printf("Merge number : %d left over Picking %d\n", mergenumber, array2[j]);
tempArray[k] = array2[j];
k++;
j++;
}
array1 = arrays_struct->array1;
for(i = 0; i < size1 + size2; i++){
array1[i] = tempArray[i];
}
printf("Merged %d and %d elements with %d duplicates\n", size1, size2, duplicates);
}
//return an array of size 50 with randomly generated integers
int *randomArray(){
srand(time(NULL));
static int array[50];
int i;
for (i = 0; i < 50; ++i){
array[i] = rand() % 51;
}
return array;
}
int main(int argc, char const *argv[])
{
int segments = 10;//make equal to argv input after testing
pthread_t threads[segments];
int i, *numbers; //iterator i, and pointer to int array 'numbers'
numbers = randomArray(); //return an array of random ints and store in 'numbers'
struct array_struct array[segments];
for(i = 0; i < segments; i++){
int *partition = numbers + (i * (50/segments));//obtain the first index of partition
array[i].partition = partition;
array[i].size = 50/segments;
pthread_create(&threads[i], NULL, sort, (void *) &array[i]);
}
for(i = 0; i < segments; i++){
pthread_join(threads[i], NULL);
}
int count = segments;
struct arrays_to_merge arrays[segments];
int j;
int size = 50/ segments;
while(count > 1){
for(i = 0, j = 0; i < count-1; j++, i += 2){
int *partition = numbers + (i * (size));
int *partition2 = numbers + (i+1 * (size));
arrays[j].array1 = partition;
arrays[j].array2 = partition2;
arrays[j].size1 = size;
arrays[j].size2 = size;
pthread_create(&threads[j], NULL, merge, (void *) &arrays[j]);
}
for(i = 0; i < j; i++){
pthread_join(threads[i], NULL);
}
size = size * 2;
count = count/2;
}
if(segments != 2){//for segments = 2, no need for his
int *partition = numbers;
int *partition2 = numbers + (size);
arrays[0].array1 = partition;
arrays[0].array2 = partition2;
arrays[0].size1 = size;
arrays[0].size2 = 50 - size;
pthread_create(&threads[0], NULL, merge, (void *) &arrays[0]);
pthread_join(threads[0], NULL);
}
for(i = 0; i < 50; i++){
printf("%d\n", numbers[i]);
}
pthread_exit(NULL);
return 0;
}
this is my output:
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 10 and 10 elements with 3 duplicates
Merged 10 and 10 elements with 1 duplicates
Merged 20 and 20 elements with 7 duplicates
Merged 40 and 10 elements with 17 duplicates
0
6
9
11
12
13
13
14
15
17
19
23
25
25
25
26
26
28
28
28
28
30
32
32
32
34
39
41
41
44
44
44
44
44
50
50
9
15
50
9
15
19
26
50
50
9
15
11
14
50
Sorry for the long wall of text, I've tried resolving this on my own and after countless hairs pulled I can't figure it out. Please help me figure out what I'm doing wrong. I think my problem lies in either the way I'm joining threads, or my merge function but since I cant be sure, i just included the whole thing.
It took a while but finally I got there :)
The problem is with this line:
int *partition2 = numbers + (i+1 * (size));
which is equivalent to (due to operator precedence).
int *partition2 = numbers + (i + size);
and is not what you want.
It should be:
int *partition2 = numbers + ((i+1) * (size));
Notice the additional brackets. Without which, the partition2 index is calculated incorrectly. Hence, merging with different parts of the array.

Random number generator output lost in transit - C [duplicate]

So the question is to develop a [5][5] table, each containing unique numbers from 1-100 (no duplicates)
so here's what I came up with:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int outerLoop;
int innerLoop;
int board[5][5]; /* Array Name And Size*/
/* seeds the random number generator*/
srand(time(NULL));
int number;
number = rand() % 101;
/* Start a loop to generate a random integer between 1 and 100 and
assign it into the array. The loop runs 25 times*/
for ( outerLoop = 0 ; outerLoop <= 25 ; outerLoop++ ) /* loop 25 times*/
{
for ( innerLoop = 0 ; innerLoop <= 4 ; innerLoop++ ) /* <=4 due to 5
columns*/
{
board[outerLoop][innerLoop] = rand() % 100 + 1;
}
printf( "%d \n", board[outerLoop][innerLoop] );
}
So I pretty much got stuck here.I'm not really sure about this:
board[outerLoop][innerLoop] = rand() % 100 + 1;
I simply made it up :/ Any idea guys?
What you want is a shuffle algorithm
Shuffle array in C
To get your 25 element array of unique #s from 1 to 100; just create a 100 element array with the numbers 1..100, shuffle the 1st 25 from the pool of 100, and use the 1st 25.
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
void shuffle(int *array, size_t array_size, size_t shuff_size)
{
if (array_size > 1)
{
size_t i;
for (i = 0; i < shuff_size - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (array_size - i) + 1);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
int main(int argc, char * argv[]) {
int a[100];
int b[5][5];
int i,j,k=0;
for(i=0; i<100;++i)
a[i]=i;
shuffle(a,100,25);
for(i=0;i<5;++i)
for(j=0;j<5;++j) {
b[i][j] = a[k++];
printf("%d ",b[i][j]);
}
printf("\n");
}
$ gcc -o test test.c
$ ./test
0 14 76 47 55 25 10 70 7 94 44 57 85 16 18 60 72 17 49 24 53 75 67 9 19
Think of it like a deck of 100 cards.
Create a 100 element array holding the card numbers (1..100)
Shuffle the array (=deck). (see #koodawg's answer and #Steve314's comment)
"Deal" yourself the first 25 cards off the deck, into your 5x5 array.
Just create array of boolean of size 100 : bool numberUsed[100]. Then in cycle:
1.Generate random number r
2.If numberUsed[r] is true, dont add that r anywhere and continue in loop
3.numberUsed[r] = true
Note that you need to use WHILE cycle with this approach, not FOR cycle.
Here is some pseudo code to solve it:
Create a "list" of length 100 containing the numbers 1...100 called "numbersAvailable"
In your inner loop set index = (int)rand() * numbersAvailable; and the take the number numbersAvailable.get(index); and then do numbersAvailable.remove(index);
In Java creating a list is easy. If you like to stick to C you have to emulate this via arrays. (I can write down the solution, but this looks like a homework, so I leave something for you).
Note: In contrast to a trial-and-reject solution, this solution has the advantage of a fixed amount of time needed to construct the result.
Since int board[5][5]; allocates a continuous amount of memory you can initialise it with just
for (i = 0; i < sizeof(board)/sizeof(int); i++)
board[0][i] = rand() % 100 + 1;
Or use a double loop like you did, but then you only need to loop 5 times in the other loop, or use sizeof to set the iteration count automatically:
for ( outerLoop = 0 ; outerLoop < sizeof(board)/sizeof(board[0]) ; outerLoop++ ) {
for ( innerLoop = 0 ; innerLoop < sizeof(board[0])/sizeof(board[0][0]) ; innerLoop++ ) {
board[outerLoop][innerLoop] = rand() % 100 + 1;
}
}
Please keep in mind that sizeof will only work on arrays in this way when the length of the array is known at compile time like it is in your example.
C stores arrays in row-major order, i.e, the elements of row 0 comes first , followed by the elements of row 1, and so forth.
We can take advantage of this by viewing int board[5][5] as int board[5*5].
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 5
int main()
{
int i, outerLoop = 1;
int board[N*N];
srand(time(NULL));
int number;
board[0] = rand() % 100 + 1; //initializing the first element
while(1)
{
number = rand() % 100 + 1 ;
if(outerLoop == N*N)
break;
else
{
//Cheking the previous elements for no duplicacy
for ( i = 0; i < outerLoop; i++)
{
if(number == board[i])
break;
}
//confirming whether all the elements are checked or not and the assigning number to the array element and then increment the counter outerLoop
if(i == outerLoop)
{
board[outerLoop] = number;
outerLoop++;
}
else
continue;
}
}
//Printing the elements of array board[N*N]
for ( outerLoop = 0 ; outerLoop < N*N ; outerLoop++ )
{
printf( "%d\t", board[outerLoop] );
if(outerLoop % N == 4)
printf("\n\n");
}
}

Function that can count how many numbers in array A fall in the range from low to high.

I'm completing a problem set for an introductory computer science class and I'm a bit confused as to what I'm supposed to be doing with this program. The question is: In one file there is a list of of scores for some participants in an athletic competition. The list is organized in the order in which the participants registered for the competition, not in order of score. A separate file contains a set of ranges. Your job is to write a program that can read the data in these two files and print a table showing how many of the participants fell into each of the given ranges.
The question is copied word for word, but I have a few questions about this question. if you could leave a comment stating your opinion about the following, that would be nice:
1) Okay, so I've written some code in order to read the numbers from the first data file, place the numbers in the array A and return a count of the number of numbers read or N, whichever is smaller. Which follows as:
#include <stdio.h>
int readNumbers(FILE* input, int A[], int N)
{
int n;
n = 0;
while (n < N&&!feof(input))
{
fscanf_s(input, "%f", &A[n]);
n++;
}
return n;
}
int count(const int A[], int N, int low, int high){
}
2) My confusion lies in using this second function to count how many numbers in array A fall in the range from low to high, inclusive. The parameter N tells you how many numbers are in the array. And use these two functions to construct and print a table of how many participants are in each of the categories given in the second file.
Now that I try to talk myself through it, I am now even more confused. Maybe I'm just making the question more difficult. Any tips will help. Thanks
to count how many numbers in array A fall in the range from low to high, inclusive.
That count() could be implemented like this
int count(const int A[], int N, int low, int high){
int i, cnt;
for (i = cnt = 0; i < N; i++) {
if (low <= A[i] && A[i] <= high)
cnt++;
}
return cnt;
}
use these two functions to construct and print a table of how many participants are in each of the categories given in the second file.
You could achieve this by using a simple loop
for (i = 0; i < number_of_categories; i++) {
printf("%d - %d : %d\n", low[i], high[i],
count(A, N, low[i], high[i]));
}
Suppose you already put all those categories information to low[] and high[].
Not sure what the input files are supposed to look like, I guessed one number per line.
Scores file:
0
1
2
3
4
5
6
7
8
9
10
19
29
39
49
59
69
79
89
99
99
99
99
99
99
99
100
Ranges File:
0
10
11
20
21
30
31
40
41
50
51
60
61
70
71
80
81
90
91
100
Source:
#include <stdio.h>
#include <stdlib.h>
int readNumbers(FILE* input, int A[], int N)
{
int n = 0;
while (n < N && !feof(input))
{
fscanf_s(input, "%d", &A[n]);
n++;
}
return n;
}
int count(const int A[], int N, int low, int high) {
int i = 0, numbers_in_range = 0;
for (i = 0; i < N; i++) numbers_in_range += (A[i] >= low && A[i] <= high) ? 1 : 0;
return numbers_in_range;
}
inline int exiting(char* reason)
{
if(reason != 0) printf("%s\n", reason);
printf("Usage: rangechecker \"scoresfilename\" \"rangesfilename\"\n");
printf("exiting...\n");
exit (-1);
}
int main(int argc, char** argv) {
int* scores = 0;
int* ranges = 0;
int num_scores = 0, num_ranges = 0;
FILE* scoresfptr;
FILE* rangesfptr;
switch (argc) {
case 1:
case 2:
exiting(0);
break;
case 3:
//verify files exist and open them
if((scoresfptr = fopen(argv[1], "r")) == NULL || (rangesfptr = fopen(argv[2], "r")) == NULL)
{
exiting("One of the files does not exist or cannot be opened.");
}
break;
default:
exiting(0);
break;
}
//kind of dumb, but because N is a passed value you kinda gotta
//know N ahead of the call to readnumber or count
//that, or I am just tired.
int ch = 0;
//assuming instructions are correct, a list, 1 number per line
//will fail if extra newlines in file
do {
ch = fgetc(scoresfptr);
if (ch == '\n')
num_scores++;
} while(ch != EOF);
//now we have N, can call readnumbers. Put file pointer back at start of file.
rewind(scoresfptr);
//Can also now allocate memory for A[].
scores = (int*)calloc(num_scores, sizeof(int));
//check return value to see if anything was read in
if(readNumbers(scoresfptr, scores, num_scores) > 0) {
//musta been something in the file
//get the ranges
ch = 0;
//assuming instructions are correct, a list, 1 number per line
do {
ch = fgetc(rangesfptr);
if (ch == '\n')
num_ranges++;
} while(ch != EOF);
//now we have N, can call readnumbers. Put file pointer back at start of file.
rewind(rangesfptr);
//Can also now allocate memory for A[].
ranges = (int*)calloc(num_ranges, sizeof(int));
//check return value to see if anything was read in
if(readNumbers(rangesfptr, ranges, num_ranges) > 0) {
//now we can call count
//print header column
printf("ranges\tscores in range\n");
for (int i = 0, j = 0; i < num_ranges/2; i++, j += 2)
{
printf("%d-%d:\t%d\n", *(ranges + j),
*(ranges + j + 1),
count(scores, num_scores, *(ranges + j),
*(ranges + j + 1)));
}
}
else {
exiting("Ranges File empty.");
}
}
else {
exiting("Scores File empty.");
}
free(scores);
free(ranges);
fclose(scoresfptr);
fclose(rangesfptr);
return(0);
}
Output:
ranges scores in range
0-10: 11
11-20: 1
21-30: 1
31-40: 1
41-50: 1
51-60: 1
61-70: 1
71-80: 1
81-90: 1
91-100: 8

Resources