Построчное чтение неопределенного количества чисел из файла - 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;
    }
}

Объяснение кода листинга программы

В этом коде:

  1. Определены две константы OUT и IN, которые используются для обозначения двух состояний, в которых может находиться программа.
  2. Инициализирована переменная state значением OUT, что означает, что программа в начале находится в состоянии вне.
  3. В цикле while происходит чтение символов из файла с помощью функции fgetc(f).
  4. Если прочитанный символ является пробелом или символом новой строки, то программа переходит в состояние вне.
  5. Если программа находится во внешнем состоянии и встречает символ, который не является пробелом или символом новой строки, то она переходит во внутреннее состояние, увеличивает счетчик n на единицу и сбрасывает значение state обратно во внешнее состояние.
  6. Цикл продолжается до тех пор, пока не будет достигнут конец файла (т.е. не будет прочитано значение EOF).

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.111 из 5
Похожие ответы