Это предварено моими главными комментариями.
Вы не можете сделать: printf(numbers[idx2]);
(то есть первый аргумент должен быть строкой формата).Итак, сделайте: printf("%d\n",numbers[idx2]);
Выполнение sizeof(numbers) / sizeof(int)
делает не точного подсчета числа фактически заполнено. Это дает максимум , в конце которого будут значения мусора.
Поскольку было так много ошибок, я не мог перечислить их все.Мне пришлось полностью рефакторинг вашего кода.Просто сравните подробно с вашим, чтобы увидеть разницу.Вы узнаете гораздо больше и быстрее, чем пытаетесь исправить то, что у вас уже есть.
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
long int
findSize(char *filename)
{
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("findSize: unable to open file '%s' -- %s\n",
filename,strerror(errno));
exit(1);
}
fseek(fp, 0L, SEEK_END);
long int res = ftell(fp);
fclose(fp);
return res;
}
int
main(int argc, char **argv)
{
char *filename = argv[1];
if (filename == NULL) {
printf("please specify a filename\n");
exit(1);
}
printf("findSize\n");
int numbers[findSize(filename)];
printf("scanf\n");
FILE *fi = fopen(filename,"r");
int size = 0;
while (1) {
if (fscanf(fi,"%d",&numbers[size]) != 1)
break;
printf("scanf: %d\n",numbers[size]);
++size;
}
fclose(fi);
printf("size: %d\n",size);
for (int idx2 = 0; idx2 < size; ++idx2)
printf("%d\n",numbers[idx2]);
int maximum = numbers[0];
for (int idx3 = 1; idx3 < size; ++idx3) {
if (numbers[idx3] > maximum)
maximum = numbers[idx3];
}
printf("Max: %d\n", maximum);
int minimum = numbers[0];
for (int idx4 = 1; idx4 < size; ++idx4) {
if (numbers[idx4] < minimum)
minimum = numbers[idx4];
}
printf("Min: %d\n", minimum);
int sum = 0;
for (int idx5 = 0; idx5 < size; ++idx5)
sum = sum + numbers[idx5];
printf("Total: %d\n", sum);
return 0;
}
ОБНОВЛЕНИЕ:
Прежде всегоСпасибо большое за вашу работу.Глядя на ваш код (я больше не могу называть его моим кодом, поскольку он совершенно другой)
Да, он был задуман как руководство для вас, чтобы написать / переписать свой собственный код, что вы и сделали.
Я вижу, что функция findSize в основном не имеет значения.
Это технически правильно, но выделит [намного] больше места, чем необходимо.
Я пытался поместить другой fscanf вместо вызова функции findSize, но я не знаю, как эта функция работает точно.
Хорошо для вас при выяснении этого альтернативного алгоритма определения размера.
Посмотрим, получу ли я его: если есть третий аргумент, он сохраняет каждый элемент чтения в третьем аргументе (который должен быть переменной).Но если третьего элемента нет и вы вводите * во второй аргумент, он нигде не хранит прочитанные элементы.Я прав?
Верьте или нет, я не использую fscanf
слишком часто, поскольку это может быть медленным, поэтому я не знаком с некоторыми из более эзотерических вариантов.Я протестировал ваш новый цикл определения размера, и он, кажется, работает, поэтому я думаю, что ваш анализ может быть правильным.
Кроме того, мы могли бы просто ввести дополнительную скалярную переменную int
и сделать:
int size = 0;
while (1) {
int val;
if (fscanf(fi,"%d",&val) != 1)
break;
++size;
}
Тем не менее, вы на самом деле второй цикл fscanf
, который используется для чтения чисел, будет не работать:
while (fscanf(fi, "%d", &numbers[size]) != 1);
Это ставит все числа в одинаковом индексе, а именно size
, что на один после конца массива numbers
, так что это неопределенное поведение.
Кроме того, условие цикла обращено от того, что должно быть, поэтому будет заполнено только одно число.
Чтобы исправить это, нам нужна дополнительная индексная переменная и нам нужно изменитьсмысл цикла while
:
int idx0 = 0;
while (fscanf(fi, "%d", &numbers[idx0]) == 1)
++idx0;
После этого изменения весь ваш обновленный код [min / max / sum] работает нормально.
Некоторые примечания постиль:
Как вы заметили, мой исходный код был немного другим (например, замена циклов while
на цикл for
s).
Но одна вещь, которую я не сделал , это повторное использование индексной переменной.То есть нет необходимости иметь отдельные для каждого цикла.Все они могут быть изменены на одну переменную idx
.
Использование разных символов не является неправильным, и может добавить ясности.Но idx
, idx1
, idx2
не так описательны, как могли бы.
Если вы хотите сохранить отдельные переменные, я бы предложил более описательные имена, такие как: inpidx
, minidx
, maxidx
и sumidx