First of all, thank you for the assist!
I\'m new to the C language (and programming in general) and I\'m trying to write a program wherein the user inputs data point
You have received a number of good answers to your question, and there are several more ways to take input of doubles
and stop on "done"
. Since you are learning C, always, ALWAYS (in case it wasn't clear), check the return of scanf
to validate the number of conversions you expected actually took place.[1] (this also provides your way to end input on "done"
(or any non-double entered causing scanf
to return less than 1
)
As noted in the comment, arrays are zero based in C. When you are taking input, you will want to use count
as your array-index, rather than i
(in this case if you exit the read on each failure -- it doesn't matter, but you could just as easily prompt again for additional input and increment count
only on a successful return from scanf
) Back to your question. If you set up your read loop to continually loop until there is a scanf
failure, you can make use of a temporary variable to initially capture the input value, and only assign the value to your array and increment your index on success. e.g. (with a constant MAXD = 1048
)
for (;;) { /* loop until scanf input fails (with 'done') */
double tmp; /* block scope declarations are fine */
printf (" data[%4d]: ", count);
if (count < MAXD && scanf(" %lf", &tmp) == 1)
data[count++] = tmp;
else
break;
}
(you can even move a copy of the prompt above the loop, and move the one above after the if (....) {...}
to eliminate the prompt when the array limit (MAXD
) is reached -- that's left as an exercise)
In the example above you have 2 conditions you enforce before storing a value. (1) you limit the number of values your user can store to MAXD
, and (2) you only store a value if a valid conversion to double
takes place in scanf
. You leave the loop if either of the conditions fails (which if you enter "done"
as a double-value, it will).
Putting the pieces together and dropping a few additional tips in the comments, you could test with something like the following:
#include
enum { MAXD = 1048 }; /* declare constants instead of using magic numbers */
int main (void) {
double data[MAXD] = {0}; /* in ISO C declarations come before code */
int i, count = 0; /* initializing variable saves debug time */
printf ("\n Welcome! \n\n Please enter each data point. "
"Enter 'done' when finished.\n\n");
for (;;) { /* loop until scanf input fails (with 'done') */
double tmp; /* block scope declarations are fine */
printf (" data[%4d]: ", count);
if (count < MAXD && scanf(" %lf", &tmp) == 1)
data[count++] = tmp;
else
break;
}
printf ("\n %d values entered:\n\n", count);
for (i = 0; i < count; i++)
printf (" data[%4d] : %.2lf\n", i, data[i]);
return 0; /* main() is type 'int' and returns a value */
}
Example Use/Output
$ ./bin/scanfdoubles
Welcome!
Please enter each data point. Enter 'done' when finished.
data[ 0]: 1.1
data[ 1]: 1.2
data[ 2]: 1.3
data[ 3]: 1.4
data[ 4]: 1.5
data[ 5]: 1.6
data[ 6]: done
6 values entered:
data[ 0] : 1.10
data[ 1] : 1.20
data[ 2] : 1.30
data[ 3] : 1.40
data[ 4] : 1.50
data[ 5] : 1.60
Look things over and let me know if you have any questions.
footnotes:
1. while you can use scanf
to take user-input in C, you are better off using a line-oriented function (like fgets
) and then parsing the complete line (with, e.g. sscanf
). The allows you to both (1) validate the read (e.g. the return of fgets
) and then (2) separately validate the value entered by the user. This decoupling of your read, and your parsing has many advantages.