Проблема в том, что вы логически пытаетесь поставить "телегу перед лошадью" . Ход программы последовательный. Вам нужно прочитать и сохранить значения, которые вы ищете, прежде чем пытаться вывести сохраненные значения. В вашем коде вы пытаетесь вывести неинициализированные (например, неопределенные ) значения до того, как получите ввод для заполнения значений (или инициализируете значения во время объявления). Как отмечено выше, это приводит к неопределенному поведению :
C11 Standard - 6.7.9 Инициализация (p10) "Если объект, который имеет automati c продолжительность хранения не инициализирована явно, ее значение не определено. " и C11 Standard - J.2 Неопределенное поведение " Используется значение объекта с автоматами c продолжительность хранения пока оно не определено (6.2.4, 6.7.9, 6.8). "
Чтобы вернуть " лошадь перед телегой ", вам нужно подумать о том, что нужно чтобы это происходило последовательно в вашем коде, чтобы убедиться, что ваши переменные правильно заполнены вводом, прежде чем вы попытаетесь вывести значения. Кроме того, если вы ничего не берете из ответа, узнайте, что вы не можете правильно использовать любую функцию ввода, если вы не проверите возврат , чтобы определить, был ли ввод успешным или неудачным.
Глядя на ваш код, кажется, что вы хотите запросить у пользователя число assignments
для ввода, а затем l oop, принимая данные для элементов массива для score, weight
и days_late
и затем отображать то, что было введено для подтвердите ввод.
При усложнении проблемы вы пытаетесь заставить пользователя ввести index
в массивах, в которых будут храниться значения (хорошо, но не нужно, если вы зацикливаетесь на вводе). Кроме того, значение index
должно быть в пределах диапазона элементов в каждом из ваших массивов, например, 0 <= index < 50
. Вы должны были бы проверить, что index
попадает в диапазон перед его использованием - или вы бы снова вызвали Undefined Behavior , пытаясь записать и прочитать значения за пределами границ вашего массива.
Чтобы устранить всю проблему index
, поскольку вы зацикливаетесь, просто прочитайте значения для присваивания, соответствующие переменной l oop. (например, вместо scores[index]
просто используйте scores[i]
в вашем l oop). Таким образом, l oop контролирует запрашиваемый и заполняемый индекс.
Собирая это вместе и проверяя каждый вход (и просто выйдите, если введена недопустимая запись), вы можете сделать что-то похожее на:
#include <stdio.h>
int main (void) {
int assignments,
i, /* for loop index for both loops */
days_late[50] = {0}, /* initialize arrays all zero */
scores[50] = {0},
weights[50] = {0};
fputs ("\nEnter No. assignments: ", stdout); /* prompt for no. assignments */
/* VALIDATE EVERY INPUT - both the conversion and that the value is within range */
if (scanf("%d", &assignments) != 1 || assignments < 0 || assignments > 49) {
fputs ("error: invalid integer input or input out of range.\n", stderr);
return 1;
}
/* loop assignments times */
for (i = 0; i < assignments; i++) {
/* display assignment no. prompt for score, weight, days_late */
printf ("\nassignment[%2d]\nenter score, weight, days_late: ", i + 1);
if (scanf ("%d%d%d", /* read and VALIDATE each value */
&scores[i], &weights[i], &days_late[i]) != 3) {
fputs ("error: invalid integer input - scores, weights, days_late.\n",
stderr);
return 1;
}
/* output values read */
printf ("\nScore just added is %d\n"
"Weight just added is %d\n"
"Lateness just added is %d\n",
scores[i], weights[i], days_late[i]);
}
return 0;
}
Обратите внимание, вы можете обрабатывать проверку ошибок более изящно, так что пользователю будет предложено повторять запрос до действительной записи сделано (или EOF
сгенерировано), но оно остается вам после разрешения входной логики c. См. Ответ на функция isalpha в C не возвращает правильное значение - для примера помечает все входные данные как символы AZ * .
Пример Использование / Вывод
$ ./bin/scoreswtsdays_late
Enter No. assignments: 2
assignment[ 1]
enter score, weight, days_late: 88 1 0
Score just added is 88
Weight just added is 1
Lateness just added is 0
assignment[ 2]
enter score, weight, days_late: 91 1 2
Score just added is 91
Weight just added is 1
Lateness just added is 2
Это охватывает мое понимание того, что вы пытаетесь. Если я что-то неправильно понял, пожалуйста, дайте мне знать, и я буду рад помочь вам. Аналогичным образом, если вам нужны дальнейшие пояснения по поводу чего-либо выше, просто оставьте комментарий ниже.
Редактировать после публикации формата входного файла
Пока нам все еще неясно, значение первой строки, учитывая ваше оставшееся описание, чтение assignments
из строки 2, а затем зацикливание assignments
раз и чтение index, scores, weights, days_late
довольно просто.
Поскольку вы читаете строку -время , вы захотите использовать линейно-ориентированную функцию ввода, такую как fgets()
(или POSIX getline()
). Обратите внимание, что строчно-ориентированные функции читают и включают '\n'
в конце каждой строки в буфере, который они заполняют (хотя здесь синтаксический анализ с sscanf
, никаких специальных приспособлений не требуется)
Для обработки вашего входного файла, просто прочитайте каждую из первых двух строк, чтобы получить необходимую информацию для чтения оставшейся части файла. НЕ забудьте проверить, что значение assignments
, считанное из строки-2, находится в пределах границ вашего массива.
Начиная с строки-3, просто прочитайте строку и затем проанализируйте значения из строки используя sscanf
, проверяем ожидаемое количество конверсий для каждой строки. Значения легко анализируются из строки с форматной строкой "%d, %d, %d, %d"
Соединяя части, вы можете сделать:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* character array used as buffer for input */
int assignments,
i = 0, /* loop counter */
days_late[50] = {0}, /* initialize arrays all zero */
scores[50] = {0},
weights[50] = {0};
if (!fgets (buf, MAXC, stdin)) { /* read/validate line 1 */
fputs ("error: insufficient input - line 1\n", stderr);
return 1;
}
/* parsing the 3 values left to you until description given */
printf ("line 1: %s", buf); /* simply output line 1 */
if (!fgets (buf, MAXC, stdin)) { /* read/validate line 2 */
fputs ("error: insufficient input - line 1\n", stderr);
return 1;
}
/* parse assignments from buf, validate in range */
if (sscanf (buf, "%d", &assignments) != 1 || assignments < 0 || assignments > 49) {
fputs ("error: invalid assignments values line - 2\n", stderr);
return 1;
}
while (i < assignments && fgets (buf, MAXC, stdin)) {
int index, score, weight, dayslate; /* temporary value to read into */
/* parse values from line, VALIDATE 4 conversion took place */
if (sscanf (buf, "%d, %d, %d, %d", &index, &score, &weight, &dayslate) != 4 ||
index < 0 || index > 49) {
fputs ("error: invalid line format, lines 3+, or index out of range\n",
stderr);
return 1;
}
scores[index] = score; /* assign values to array[index] */
weights[index] = weight;
days_late[index] = dayslate;
/* output values read */
printf ("\nassignment[%2d]:\n"
" Score just added is : %d\n"
" Weight just added is : %d\n"
" Lateness just added is: %d\n",
index, scores[index], weights[index], days_late[index]);
i++; /* increment counter */
}
return 0;
}
Пример использования / Вывод
Если ваш входной файл находится в dat/scoreswtsdays.txt
, запуск программы при перенаправлении файла данных в качестве ввода приведет к следующему:
$ ./bin/scoreswtsdays_late_file < dat/scoreswtsdays.txt
line 1: 10 0 Y
assignment[ 2]:
Score just added is : 80
Weight just added is : 40
Lateness just added is: 0
assignment[ 1]:
Score just added is : 100
Weight just added is : 60
Lateness just added is: 0
Снова посмотрите и дайте мне знать, если у вас есть дополнительные вопросы.