Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/14: Рейтинг темы: голосов - 14, средняя оценка - 4.57
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
1

Построчное чтение неопределенного количества чисел из файла

07.10.2012, 23:02. Показов 2813. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здраствуйте. У меня программа построчно читает числа из файла в масив. Потом выполняется сортировка этих чисел. И на конец запись отсорированого набора чисел в тот же файл. Но меня смущает тот факт, что приходится читать файл два раза: первый раз для определения количества чисел, второй раз для считывания самих чисел. Ибо считываю я в масивы, а для масива я выделяю память, а чтобы знать сколько ее нужно выделить мне нужно знать сколько в файле чисел. Использование realoc(); 16 тысяч раз, при чем, это в лучшем случае, вобще чисел может быть и 160 тысяч, тоже както выглядет не очень хотя, к винчестеру так же часто обращатся не многим лучше
Дайте пожалуйста совет как можно уменьшить нагрузку на винчестер, не дергая его по пустякам лишних 160к раз, ну или вобще какой нибудь совет
Вот код моей программы:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#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;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.10.2012, 23:02
Ответы с готовыми решениями:

Построчное чтение чисел из файла и последующая запись в HashSet
Привет форумчане! Возникли небольшие трудности,есть задача: Создать массив из 10000 количества...

Построчное чтение целых чисел из текстового файла с занесением в массив для анализа
Доброго всем здравия! Я новичок в С++, и у меня существует большая необходимость в решении...

Построчное чтение из файла
Из файла нужно построчно считать числа типа double и записать в массив. Файл примерно выглядит...

построчное чтение файла
Доброе утро! Мне требуется помощь в следующем у меня есть файл, примерно следующего вида: Имя...

10
349 / 299 / 166
Регистрация: 15.03.2012
Сообщений: 653
Записей в блоге: 1
08.10.2012, 00:30 2
Чтобы определить количество чисел можно сделать так.
C
1
2
3
4
if(f = fopen(v[1], "r")) {
    fseek(f, 0L, SEEK_END);
    long n = ftell(f) / sizeof(int);
}
1
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
08.10.2012, 00:51  [ТС] 3
угу спасибо попробую
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
08.10.2012, 03:52 4
не надо файл закрывать, просто сделай rewind()

C
1
2
    while(fscanf(f, "%d", &i) == 1)
        n++;
1
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
08.10.2012, 12:25  [ТС] 5
Цитата Сообщение от СашаН Посмотреть сообщение
Чтобы определить количество чисел можно сделать так.
C
1
2
3
4
if(f = fopen(v[1], "r")) {
    fseek(f, 0L, SEEK_END);
    long n = ftell(f) / sizeof(int);
}
Пардоньте, а разве это для текстовых файлов подойдет? мало того что там число может занимать далеко не 4 байта, или же наборот более 4 байт, так там же еще есть по два байта в каждой строчке на символ возврата каретки и переноса на новую строчку(если я не ошибаюсь в windows именно так). помоему, такой вариант явно не подойет
1
349 / 299 / 166
Регистрация: 15.03.2012
Сообщений: 653
Записей в блоге: 1
08.10.2012, 13:54 6
Да, в этом случае нужно будет два раза пройтись.
Тогда вот эта конструкция будет быстрее и экономнее чем с fscanf().
C
1
2
3
4
5
6
7
8
9
10
11
12
#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
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
08.10.2012, 14:09 7
Цитата Сообщение от СашаН Посмотреть сообщение
быстрее и экономнее чем с fscanf()
"1 2 3 a a a" даст 6
0
349 / 299 / 166
Регистрация: 15.03.2012
Сообщений: 653
Записей в блоге: 1
08.10.2012, 14:25 8
Цитата Сообщение от accept Посмотреть сообщение
"1 2 3 a a a" даст 6
Правильно. ?
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
08.10.2012, 14:41 9
fscanf() проверяет ещё числа
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
08.10.2012, 15:15 10
lowercase, если не хотите 100500 раз realloc() вызывать (что в общем правильно), посмотрите, как в C++ STL класс vector реализован. Основная идея - памяти под массив выделяется заранее с запасом. Если в процессе заполнения её (выделенной памяти) не хватает - выделяется ещё и снова с запасом. Алгоритм вычисления количества дополнительной памяти может быть самый разнообразный - можно тупо по 512 байт к примеру наращивать, можно таки отслеживать позицию в файле, чтобы по отношению её к длине файла и прочитанному количеству чисел примерно вычислять, сколько ещё в файле чисел может остаться. Ну а когда весь файл прочитан - ещё раз realloc() чтобы пустой хвост удалить, если он будет. Ещё вариант - читать числа в список, а не в массив. Профит - прочитать так заранее неизвестное количество данных из файла действительно легче. В минусе - накладные расходы памяти и более замороченная (хоть и не на много) сортировка. И кстати - а чем Вам при массиве стандартная qsort() не угодила?
2
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
08.10.2012, 20:07  [ТС] 11
спасибо за советы буду разбиратся.

Цитата Сообщение от easybudda Посмотреть сообщение
а чем Вам при массиве стандартная qsort() не угодила?
чесно говоря я даже не знал что она есть
да и для всеобщего развития, как говорится, непомешает попробовать самому
я ж это, только начинающий сишник
0
08.10.2012, 20:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.10.2012, 20:07
Помогаю со студенческими работами здесь

Построчное чтение файла
Например есть структура struct Record { char * Name; char * LastName; int Age; }; и...

Построчное чтение из файла
Помогите написать программу которая считывает из файла такой структуры; 1 строка ...

Построчное чтение из файла
Здравствуйте! Как читать из текстового файла построчно? То есть имеется file.txt, //file.txt...

Построчное чтение из файла
Необходимо построчно прочитать данные из файла, из разобрать их по переменным. Образец данных в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru