Вы получили ряд хороших ответов на свой вопрос, и есть еще несколько способов сделать ввод doubles
и остановиться на "done"
. Так как вы изучаете C, всегда, ВСЕГДА (в случае, если это не было ясно), проверки возвращениеscanf
для проверки количества конверсий вы ожидали на самом деле имели место. [1] (это также ваш путь для завершения ввода на "done"
(или любой недвоеные Введенный вызывая scanf
вернуть менее 1
)
Как отмечено в комментарии, массивы с нуля в C. Когда вы принимаете ввод, вы хотите использовать count
как ваш индекс массива, а не i
(в этом случае, если вы выходите из чтения при каждом сбое - это не имеет значения, но вы можете так же легко снова запросить дополнительный ввод и приращение count
только при успешном возврате с scanf
) Назад к вашим запросам Тион. Если вы сконфигурируете цикл чтения для непрерывного цикла до тех пор, пока не произойдет сбой scanf
, вы можете использовать временную переменную для первоначального захвата входного значения и назначить значение только вашему массиву и привить индекс к успеху. например (С постоянной 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;
}
(вы можете даже переместить копию строки выше цикла, и переместить одну выше после if (....) {...}
устранить подсказку, когда предел массива (MAXD
) достигается - это осталось как упражнение)
В приведенном выше примере у вас есть 2 условия, которые вы выполняете перед сохранением значения.(1) вы ограничиваете количество значений, которое может хранить ваш пользователь до MAXD
, и (2) вы сохраняете только значение, если действительное преобразование в double
происходит в scanf
. Вы покидаете цикл, если какое-либо из условий не работает (что, если вы введете "done"
в качестве двойного значения, оно будет).
Ввод куски вместе и сбросив несколько дополнительных советов в комментариях, вы можете испытать что-то вроде следующего:
#include <stdio.h>
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 */
}
Пример использования/вывода
$ ./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
Посмотрите вещи над и дайте мне знать, если у вас есть какие-либо вопросы.
сносок:
1. в то время как вы можете использовать scanf
принять ввод пользователя в C, вы лучше использовать строковый функцию (например, fgets
), а затем разбор всей строки (например, sscanf
). Это позволяет вам (1) проверять чтение (например, возврат fgets
), а затем (2) отдельно проверять значение, введенное пользователем. Это развязка вашего чтения, и ваш синтаксический анализ имеет много преимуществ.
Тип данных для данных - двойные двойные данные [1048]; и вы приравниваете его к значениям char. Это ошибка типа. Если вы хотите приравнивать, используйте длинный, а не двойной. Двойной тип с плавающей точкой. – xCodeZone
Okey, okey. Как это было скомпилировано? – Inline
'' 'для значений типа' char', который представляет собой только один символ. Не имеет смысла писать '' done'', это строка. – Barmar