Построчное чтение неопределенного количества чисел из файла - C (СИ)
Формулировка задачи:
Здраствуйте. У меня программа построчно читает числа из файла в масив. Потом выполняется сортировка этих чисел. И на конец запись отсорированого набора чисел в тот же файл. Но меня смущает тот факт, что приходится читать файл два раза: первый раз для определения количества чисел, второй раз для считывания самих чисел. Ибо считываю я в масивы, а для масива я выделяю память, а чтобы знать сколько ее нужно выделить мне нужно знать сколько в файле чисел. Использование realoc(); 16 тысяч раз, при чем, это в лучшем случае, вобще чисел может быть и 160 тысяч, тоже както выглядет не очень хотя, к винчестеру так же часто обращатся не многим лучше
Дайте пожалуйста совет как можно уменьшить нагрузку на винчестер, не дергая его по пустякам лишних 160к раз, ну или вобще какой нибудь совет
Вот код моей программы:
#include <stdio.h> void swap(int* a, int* b){ int t = *a; *a = *b; *b = t; } void sort(int a[], int first, int last){ int i = first, j = last, x = a[(first + last) / 2]; do{ while(a[i] < x) i++; while(a[j] > x) j--; if(i <= j){ if(i < j) swap(&a[i], &a[j]); i++; j--; } } while (i <= j); if(i < last) sort(a, i, last); if(first < j) sort(a, first, j); } int main(int n, char *v[]){ if(n < 2) { printf("Unspecified filename\n"); return 1; } FILE* f; n = 0; int i; if(f = fopen(v[1], "r")) { while(!feof(f)){ fscanf(f,"%d", &i); n++; } fclose(f); } else { printf("Can\'t open file \"%s\".\n", v[1]); return 1; } int* x = (int*)malloc(n * sizeof(int)); if(f = fopen(v[1], "r")) { for(i = 0; i < n; i++) fscanf(f,"%d\n", &x[i]); fclose(f); } else { printf("Can\'t open file \"%s\".\n", v[1]); free(x); return 1; } sort(x, 0, n - 1); if(f = fopen(v[1], "w")) { for(i = 0; i < n-1; i++) fprintf(f, "%d\n",x[i]); fclose(f); } else { printf("Can\'t create file \"%s\".\n", v[1]); free(x); return 1; } free(x); return 0; }
Решение задачи: «Построчное чтение неопределенного количества чисел из файла»
textual
Листинг программы
#define OUT 1 #define IN 0 state = OUT; int c; while ((c = fgetc(f))!=EOF) { if (c == ' ' || c == '\n') state = OUT; else if (state == OUT) { state = IN; ++n; } }
Объяснение кода листинга программы
В этом коде:
- Определены две константы
OUT
иIN
, которые используются для обозначения двух состояний, в которых может находиться программа. - Инициализирована переменная
state
значениемOUT
, что означает, что программа в начале находится в состояниивне
. - В цикле
while
происходит чтение символов из файла с помощью функцииfgetc(f)
. - Если прочитанный символ является пробелом или символом новой строки, то программа переходит в состояние
вне
. - Если программа находится во внешнем состоянии и встречает символ, который не является пробелом или символом новой строки, то она переходит во внутреннее состояние, увеличивает счетчик
n
на единицу и сбрасывает значениеstate
обратно во внешнее состояние. - Цикл продолжается до тех пор, пока не будет достигнут конец файла (т.е. не будет прочитано значение
EOF
).
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д