Я пытаюсь отобразить список желаний в командной строке. Пользователь вводит стоимость предмета, уровень приоритета (1-3) и наличие вариантов финансирования (да/нет). Введенные значения помещаются в несколько массивов. После того, как пользователь введет все свои значения, они отображаются в таблице в конце.
Все в моем коде работает нормально, за исключением случаев, когда я пытаюсь распечатать введенные пользователем значения стоимости (double itemCosts[numOfItems];) в таблице. Первый и последний элементы не печатаются должным образом, даже если я ввожу одинаковую цену (6225,88) для всех из них. Последний элемент всего 0.000000. См. прилагаемый рисунок вывода таблицы.
Я попытался отладить проблему, разделив циклы, связанные со стоимостью, и скомпилировав/запустив их как другой файл, и затраты отображаются правильно... поэтому я думаю, что ошибка где-то в другом месте, но я не могу ее найти.
#define MAX_ITEMS 10
#include <stdio.h>
int main()
{
const double MIN_INCOME = 500, MAX_INCOME = 400000;
int numOfItems;
double netIncome, itemTotal;
double itemCosts[numOfItems];
int itemPriors[numOfItems];
char itemFinOps[numOfItems];
printf("+--------------------------+\n");
printf("+ Wish List Forecaster |\n");
printf("+--------------------------+\n\n");
// Prompt for net monthly income
do
{
printf("Enter your monthly NET income: $");
scanf("%lf", &netIncome);
if (netIncome < MIN_INCOME)
{
printf("ERROR: You must have a consistent monthly income of at least $500.00\n\n");
}
else if (netIncome > MAX_INCOME)
{
printf("ERROR: Liar! I'll believe you if you enter a value no more than $400000.00\n\n");
}
} while (!(netIncome >= MIN_INCOME && netIncome <= MAX_INCOME));
printf("\n");
// Prompt for # of wish list items
do
{
printf("How many wish list items do you want to forecast?: ");
scanf("%d", &numOfItems);
if (!(numOfItems > 0 && numOfItems <= MAX_ITEMS))
{
printf("ERROR: List is restricted to between 1 and 10 items.\n\n");
}
printf("\n");
} while (!(numOfItems > 0 && numOfItems <= MAX_ITEMS));
// Store wish list item details
for (int i = 0; i < numOfItems; i++)
{
printf("Item-%d Details:\n", i + 1);
do //////////////// ******** PROMPT COST ********** //////////
{
printf("Item cost: $");
scanf("%lf", &itemCosts[i]);
if (!(itemCosts[i] >= (double)100))
{
printf(" ERROR: Cost must be at least $100.00\n");
}
} while (!(itemCosts[i] >= (double)100));
do // prompt priority
{
printf("How important is it to you? [1=must have, 2=important, 3=want]: ");
scanf("%d", &itemPriors[i]);
if (!(itemPriors[i] >= 1 && itemPriors[i] <= 3))
{
printf(" ERROR: Value must be between 1 and 3\n");
}
} while (!(itemPriors[i] >= 1 && itemPriors[i] <= 3));
do // prompt finance options
{
printf("Does this item have financing options? [y/n]: ");
scanf(" %c", &itemFinOps[i]);
if (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n'))
{
printf(" ERROR: Must be a lowercase 'y' or 'n'\n");
}
} while (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n'));
printf("\n");
}
///////// display summary of item details in TABLE //////////
printf("Item Priority Financed Cost\n");
printf("---- -------- -------- -----------\n");
for (int j = 0; j < numOfItems; j++)
{
printf(" %d %d %c %lf\n", j + 1, itemPriors[j], itemFinOps[j], itemCosts[j]);
itemTotal += itemCosts[j];
}
return 0;
}
Нут, В стороне: Упрощение: (double)100 --> 100.0
int numOfItems;
double netIncome, itemTotal;
double itemCosts[numOfItems];
int itemPriors[numOfItems];
char itemFinOps[numOfItems];
Это неопределенное поведение, так как ваш numOfItems не инициализирован. В C таблица не будет увеличиваться или уменьшаться до размера при изменении этой переменной
Изменить на:
double itemCosts[MAX_ITEMS];
int itemPriors[MAX_ITEM];
char itemFinOps[MAX_ITEM];
Всегда проверяйте результат scanf. Пример:
if (scanf("%lf", &netIncome) != 1){ /* handle error*/}
Как сказал Влад из Москвы и 0___________, нельзя определить массив, используя не инициализированную переменную для количества его элементов. Вы можете определить переменные как
double *itemCosts;
int *itemPriors;
char *itemFinOps;
И после того, как переменной numOfItems будет присвоено значение, вы динамически выделяете память следующим образом:
itemCosts = (double*) malloc(numOfItems * sizeof(double));
itemPriors = (int*) malloc(numOfItems * sizeof(int));
itemFinOps = (char*) malloc(numOfItems * sizeof(char));
Или
itemCosts = (double*) calloc(numOfItems, sizeof(double));
itemPriors = (int*) calloc(numOfItems, sizeof(int));
itemFinOps = (char*) calloc(numOfItems, sizeof(char));
Calloc инициализирует все элементы массива 0
В конце вы должны освободить выделенную память:
free(itemCosts);
free(itemPriors);
free(itemFinOps);
Вы должны будете сделать это бесплатно при каждом взаимодействии
Вы правы, я обновил ответ
Эти объявления удваивают itemCosts[numOfItems]; int itemPriors[numOfItems]; char itemFinOps[numOfItems]; имеют неопределенное поведение, поскольку переменная numOfItems не инициализирована.