Continuing for my initial comment, whenever you want to capture the frequency of values within a range, you generally want to declare an array and let each element of the array represent one value within the range. (this applies to integer input). For example, in your case, if you want to find the frequency of the integer values entered by a user in the range of 0-99
, you would declare an array with 100 elements (representing values 0-99
) and initialize all values to 0
.[1]
Then each time the user enters a valid value in the range, you increment that element. For example, if your user enters 58
, you would increment array[58] = array[58] + 1;
(or simply array[58]++;
). The value of array[58]
is now 1
indicating the user has entered 58
once. (if 58
was entered again, it would be 2
, and so on...)
This lends itself nicely for your input loop. You simply declare say int x;
and in your scanf
call, you fill x
, validate it is within the range and then array[x]++;
For example with your numarray
declared as int [100]
, you could do [2]:
#define NMAX 100 /* define constants, avoid 'magic' numbers in code */
...
for (;;) { /* loop until non-numeric encountered */
int x;
if (scanf("%d", &x) != 1) /* check for non-numeric */
break;
if (x < 0 || x >= NMAX) { /* validate value in range */
fprintf (stderr, "error: value outside of range -- "
"try again.
");
continue; /* if out of range - get new number */
}
numarray[x]++; /* increment frequency at element x */
}
Now in your case the 0-99
exactly matches the zero-based array indexing used in C, but you can index any range simply by adjusting the indexes. For example, if you were interested in a range of 50-150
you would simply adjust the indexes as required (e.g. numarray[x-50]++;
)
However, in your code, it is quite unclear what your actual intent is. For instance you ask for values between 0-99
, but then declare numarray
as a floating-point type. If your intent was to have the user enter whole number values, then your array type should be an integer type instead. That reduces to the classic frequency problem which you could handle simply in a manner similar to the following:
#include <stdio.h>
#include <stdlib.h>
#define NMAX 100 /* define constants, avoid 'magic' numbers in code */
int main (void){
int i, numarray[NMAX] = {0}; /* C favors all lower-case over
* camelCase variable names */
printf ("Enter any number of integers between 0 and 99 "
"followed a non-numeric:
");
for (;;) { /* loop until non-numeric encountered */
int x;
if (scanf("%d", &x) != 1) /* check for non-numeric */
break;
if (x < 0 || x >= NMAX) { /* validate value in range */
fprintf (stderr, "error: value outside of range -- "
"try again.
");
continue; /* if out of range - get new number */
}
numarray[x]++; /* increment frequency at element x */
}
for (i = 0; i < NMAX; i++) /* output frequency of values */
printf (" %2d : %d times
", i, numarray[i]);
return EXIT_SUCCESS;
}
Example Use/Output
For example, you can generate 500
values between 0-99
and output the frequency for each of the 500
numbers generated with something similar to the following:
$ ./bin/freqarray < <(for i in $(seq 1 500); do
printf " %d" $(($RANDOM %100)); done; echo "done")
Enter any number of integers between 0 and 99 followed a non-numeric:
0 : 4 times
1 : 7 times
2 : 7 times
3 : 4 times
4 : 5 times
5 : 11 times
6 : 5 times
7 : 5 times
8 : 3 times
9 : 8 times
10 : 5 times
...
90 : 8 times
91 : 2 times
92 : 5 times
93 : 8 times
94 : 4 times
95 : 4 times
96 : 8 times
97 : 6 times
98 : 4 times
99 : 8 times
Handling floating-point values
Now if you truly wanted your user to enter floating-point values, e.g. 58.01831
, 58.01826538
, etc..., conceptually accounting for the frequency of each number isn't any difference, but the implementation is much more involved given the way floating-point numbers are stored in memory. See IEEE floating point and the numerous post on this site. The problems related to floating point storage and exact comparison of random user input can become fairly involved -- quickly. Even for the range of 0-99
there are literally 4e+18
+ 64-bit values involved.
As noted in the second comment, one approach that can help is to hash the input values and store the hashed values in a hash-table to reduce the size of the array needed to track/store all values. You will have to balance precision you keep against storage size.
There is no way you could declare an array of 4e+18
elements. A hash table essentially provides a storage and lookup mechanism that can give you reasonable accuracy, and also provides a reasonable storage size. If the user enters 2-values that have the same hash a collision will be generated in your table, which you could use to indicate a duplicate entry. If that was your intent, then you will need to investigate the floating point hash functions available to meet your needs (which from your question, doesn't seem like what you intended, and it well beyond full-explanation here)
Look things over and let me know if you have any questions. If your intent was different, then please edit the question and I'm happy to work with you further.
footnote 1: choose an array type capable of holding the maximum number of entries you expect, e.g. each int
element of the array can capture a maximum of INT_MAX
, or 2147483647
repetitions (where an int
is 32-bits
)
footnote 2: C generally favors variable names of all lower-case, and avoids the use of camelCase or MixedCase variable names; reserving all upper-case for constants and macros. It is a matter of style -- so it is completely up to you.