Функция ограничения занятости памяти - С
-
Ginger
Функция ограничения занятости памяти - С
Пишу прогу на С.
в неё входит создание маленькой БД.
использую arrays of records and files
как я не крутила так и не нашла способа не задавать явное колличество записей в БД. т.е. что бы файл растягивался как резиновый по мере поплнения бд или удаления из неё записей.
подумала о том чтобы за ранее обозначить бОльшее число записей в array, допустим сразу 1000, и пополнять по мере необходимости.
но тогда в памяти и будет занимать место для всей 1000 даже если там всего 10 записей.
слышала есть спец. функция, которая ограничивает занятость памяти для array на колличество заполненных ентри. т.е. даже если арей на 1000, а занято всего 10, то память будет занимать только под 10.
подскажите что за функция? желательно с синтаксисом, плз.
[s]Исправлено: Ginger, 16:25 25-01-2004[/s]
в неё входит создание маленькой БД.
использую arrays of records and files
как я не крутила так и не нашла способа не задавать явное колличество записей в БД. т.е. что бы файл растягивался как резиновый по мере поплнения бд или удаления из неё записей.
подумала о том чтобы за ранее обозначить бОльшее число записей в array, допустим сразу 1000, и пополнять по мере необходимости.
но тогда в памяти и будет занимать место для всей 1000 даже если там всего 10 записей.
слышала есть спец. функция, которая ограничивает занятость памяти для array на колличество заполненных ентри. т.е. даже если арей на 1000, а занято всего 10, то память будет занимать только под 10.
подскажите что за функция? желательно с синтаксисом, плз.
[s]Исправлено: Ginger, 16:25 25-01-2004[/s]
-
Ginger
Re: Функция ограничения занятости памяти - С
нашла, кажется, выход с безразмерными structures:
Код:
так. мне ясно до fwrite(&r,sizeof(struct rec),
а это что такое - 1,f); ?
[s]Исправлено: Ginger, 18:24 25-01-2004[/s]
Код:
Код: Выделить всё
#include <stdio.h>
/* random record description - could be anything */ *
struct rec *
{ * * * *
* *int x,y,z; *
};
/* writes and then reads 10 arbitrary records from the file "junk". */
void main() *
{ * *
* *int i; * *
* *FILE *f; * *
* *struct rec r;
* *
* */* create the file of 10 records */ * *
* *f=fopen("junk","w"); * *
* *for (i=1;i<=10; i++) * *
* *{ * * *
* * * *r.x=i; * * *
* * * *fwrite(&r,sizeof(struct rec),1,f); * *
* *} * *
* *fclose(f);
}так. мне ясно до fwrite(&r,sizeof(struct rec),
а это что такое - 1,f); ?
[s]Исправлено: Ginger, 18:24 25-01-2004[/s]
-
Ginger
Re: Функция ограничения занятости памяти - С
ivank
Цитата:
В общем-то добавление и чтение сделаны как я и сказал
я вобще мало поняла, что ты сказал...
Цитата:
Кстати, ещё более простой метод удаления
а можно не перекидывать всё опять, а переименовать файлы. старый в bak а новый в его имя.
нужно попробовать.
Цитата:
Должно быть veg.scanf("%i",&veg.caloricity); наверно
ой, наверно! после того как запостила, обнаружила, что он мне вместо якобы вводимых 345, к примеру, выдаёт 1.
отркыла файл, посмотрела - там и записан 1. значит читает не верно. короче покрутила, повертела не поняла, как сделать (примера ни одного не нашла) и сделал через float.
надо твой вариант попробовать! только выглядит как в object oriented...
а как редактирование осуществить?
Добавлено:
вобщем не
Цитата:
veg.scanf("%i",&veg.caloricity);
а scanf("%i",&veg.caloricity); и всё ок стало!
[s]Исправлено: Ginger, 2:22 29-01-2004[/s]
Цитата:
В общем-то добавление и чтение сделаны как я и сказал
я вобще мало поняла, что ты сказал...
Цитата:
Кстати, ещё более простой метод удаления
а можно не перекидывать всё опять, а переименовать файлы. старый в bak а новый в его имя.
нужно попробовать.
Цитата:
Должно быть veg.scanf("%i",&veg.caloricity); наверно
ой, наверно! после того как запостила, обнаружила, что он мне вместо якобы вводимых 345, к примеру, выдаёт 1.
отркыла файл, посмотрела - там и записан 1. значит читает не верно. короче покрутила, повертела не поняла, как сделать (примера ни одного не нашла) и сделал через float.
надо твой вариант попробовать! только выглядит как в object oriented...
а как редактирование осуществить?
Добавлено:
вобщем не
Цитата:
veg.scanf("%i",&veg.caloricity);
а scanf("%i",&veg.caloricity); и всё ок стало!
[s]Исправлено: Ginger, 2:22 29-01-2004[/s]
-
ivank
Re: Функция ограничения занятости памяти - С
Внимательно читаем документацию на ф-ии scanf и gets. В частности, scanf после считывания числа, оставляет символа перехода на новую строку во входном потоке, если его специально не попросить его убрать. А ф-ия gets, как известно считывает до первого '\n', поэтому наткнувшись на этот символ, не убранный ещё scanf'ом она сразу завершает свою работу.
Должно быть так: scanf("%d\n",&veg.caloricity );
Если, число записано на отдельной строке, то его можно считать в строку (т.е. массив char), а затем sscanf'ом или atoi перевести в число.
Должно быть так: scanf("%d\n",&veg.caloricity );
Если, число записано на отдельной строке, то его можно считать в строку (т.е. массив char), а затем sscanf'ом или atoi перевести в число.
-
ivank
Re: Функция ограничения занятости памяти - С
Ginger
Причём тут безразмерные структуры не ясно. Обычный RANDOM access к файлу.
Если всё хранится в файле, то вполне подойдёт связка fseek/ftell. Если надо запись надо удалить, то просто помечаешь её как удалённую (т.к. сдвигать все последующие слишком долго). И изредка сжимаешь БД сдвигая все записи на места удалённых. Так работают некоторые dbm-базы. Правда, там ещё поле-ключ поддерживается, но это детали. Там просто балансируемое при доступе дерево с ключами в начале файла в простейшем случае сойдёт.
На счёт fwrite:
Цитата:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
Parameters
buffer
Pointer to data to be written
size
Item size in bytes
count
Maximum number of items to be written
stream
Pointer to FILE structure
Добавлено:
RANDOM д.б. написано маленькими буквами, а безразмерных структур вообще не существует.
Причём тут безразмерные структуры не ясно. Обычный RANDOM access к файлу.
Если всё хранится в файле, то вполне подойдёт связка fseek/ftell. Если надо запись надо удалить, то просто помечаешь её как удалённую (т.к. сдвигать все последующие слишком долго). И изредка сжимаешь БД сдвигая все записи на места удалённых. Так работают некоторые dbm-базы. Правда, там ещё поле-ключ поддерживается, но это детали. Там просто балансируемое при доступе дерево с ключами в начале файла в простейшем случае сойдёт.
На счёт fwrite:
Цитата:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
Parameters
buffer
Pointer to data to be written
size
Item size in bytes
count
Maximum number of items to be written
stream
Pointer to FILE structure
Добавлено:
RANDOM д.б. написано маленькими буквами, а безразмерных структур вообще не существует.
-
Ginger
Re: Функция ограничения занятости памяти - С
говоря о размере я имела ввиду функцию - sizeof()
о fwrite() спросила, потому что не знаю синтаксиса, а не потому что считаю, что она как-то на размер файла влияет
и это всё не главное. мой главный вопрос в первом посте:
Цитата:
подскажите что за функция? желательно с синтаксисом, плз.
Цитата:
а безразмерных структур вообще не существует.
вот про это и спич.
о fwrite() спросила, потому что не знаю синтаксиса, а не потому что считаю, что она как-то на размер файла влияет
и это всё не главное. мой главный вопрос в первом посте:
Цитата:
подскажите что за функция? желательно с синтаксисом, плз.
Цитата:
а безразмерных структур вообще не существует.
вот про это и спич.
-
ivank
Re: Функция ограничения занятости памяти - С
Какое имеет отношение sizeof к безразмерности не ясно.
Начнём с простого вопроса: хранится вся информация в файле или в памяти? В оригинальном посте это не очевидно (мне во всяком случае). А так же, храниться должно всё именно как массив (т.е. в программе присутствует доступ по индексу) или как угодно/удобно?
Если в файле, то см. предыдущий мой ответ. Т.е. надо курить доументацию поблочному вводу выводу, а так же ф-иям установки/чтения позиции в файле. Весь необходимый арсенал ф-ий в этом случае: fopen, fclose, fwrite, freed, fseek, ftell.
Далее, если мы пользуем C++ и всё хранится в памяти, то вполне подойдёт stdd:vector/std::deque (в случае массива) или std::list (если присутствует только последовательный доступ к элементам).
Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc.
Ну и от связных списков и более нетривиальных структур, реализованных ручками тоже никто отказываться не собирается.
В общем, если чуть поточнее будут поставлены условия, то любой из этих способов можно будет рассмотреть поподробнее.
Начнём с простого вопроса: хранится вся информация в файле или в памяти? В оригинальном посте это не очевидно (мне во всяком случае). А так же, храниться должно всё именно как массив (т.е. в программе присутствует доступ по индексу) или как угодно/удобно?
Если в файле, то см. предыдущий мой ответ. Т.е. надо курить доументацию поблочному вводу выводу, а так же ф-иям установки/чтения позиции в файле. Весь необходимый арсенал ф-ий в этом случае: fopen, fclose, fwrite, freed, fseek, ftell.
Далее, если мы пользуем C++ и всё хранится в памяти, то вполне подойдёт stdd:vector/std::deque (в случае массива) или std::list (если присутствует только последовательный доступ к элементам).
Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc.
Ну и от связных списков и более нетривиальных структур, реализованных ручками тоже никто отказываться не собирается.
В общем, если чуть поточнее будут поставлены условия, то любой из этих способов можно будет рассмотреть поподробнее.
-
Ginger
Re: Функция ограничения занятости памяти - С
ivank
вобщем прога вычесляет коллории.
при этом она хранит данные в нескольких файлах, которые представляют собой отдельные категории - мясо, хлеб, овощи, фрукты. в каждой категории хранятся данные (имя продукта и его каллорийность) неограниченного чилса продуктов. т.к. нужно чтобы юзер мог и добавить новый продукт в конкретную категорию и удалить, и править.
при этом имя продукта - чар
каллорийность - инт
потому что каллорийность будет использоваться в вычеслениях.
так вот я и думаю, как это дело организовать по умному.
Цитата:
Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc.
это я тоже нашла, но одно НО - нам этого не давали. нам файлы-то 2 дня назад без особого углубления дали. поэтому могут счесть за ненужные усложнения.
я тут порылась и придумала приблизительно такой выход:
для каждой категории заводим отдельный файл
имя продукта и его каллорийность записываем через строку, т.е:
белый хлеб
226
чёрный хлеб
214
...
когда нам нужно мы находим (юзер будет вводить имя продукта, а прога находить его каллорийность и вычеслять что там надо) каллорийность переводим его из чар в инт (т.к. я не знаю как хранить каллорийность как инт):
callor=(int)value_of_caloricity
(вроде так можно)
и делаем вычесления.
конечно был ещё "выход":
создать struct { char name[40]; int caloricity;} для каждой категории..
при этом записей должно быть какое-то колличество, т.е. arrays of records
вот я с самого начала и спросила - есть ли функция ограничения занятости памяти до заполненного коллическва ентриес в аррей...
но это ещё ладно, а вот как это дело запихать в файл и как потом от туда так же считать... я не знаю...
[s]Исправлено: Ginger, 0:38 26-01-2004[/s]
вобщем прога вычесляет коллории.
при этом она хранит данные в нескольких файлах, которые представляют собой отдельные категории - мясо, хлеб, овощи, фрукты. в каждой категории хранятся данные (имя продукта и его каллорийность) неограниченного чилса продуктов. т.к. нужно чтобы юзер мог и добавить новый продукт в конкретную категорию и удалить, и править.
при этом имя продукта - чар
каллорийность - инт
потому что каллорийность будет использоваться в вычеслениях.
так вот я и думаю, как это дело организовать по умному.
Цитата:
Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc.
это я тоже нашла, но одно НО - нам этого не давали. нам файлы-то 2 дня назад без особого углубления дали. поэтому могут счесть за ненужные усложнения.
я тут порылась и придумала приблизительно такой выход:
для каждой категории заводим отдельный файл
имя продукта и его каллорийность записываем через строку, т.е:
белый хлеб
226
чёрный хлеб
214
...
когда нам нужно мы находим (юзер будет вводить имя продукта, а прога находить его каллорийность и вычеслять что там надо) каллорийность переводим его из чар в инт (т.к. я не знаю как хранить каллорийность как инт):
callor=(int)value_of_caloricity
(вроде так можно)
и делаем вычесления.
конечно был ещё "выход":
создать struct { char name[40]; int caloricity;} для каждой категории..
при этом записей должно быть какое-то колличество, т.е. arrays of records
вот я с самого начала и спросила - есть ли функция ограничения занятости памяти до заполненного коллическва ентриес в аррей...
но это ещё ладно, а вот как это дело запихать в файл и как потом от туда так же считать... я не знаю...
[s]Исправлено: Ginger, 0:38 26-01-2004[/s]
-
Ginger
Re: Функция ограничения занятости памяти - С
ну обьясните хотя бы как struct Vegetables { char name[40]; int caloricity;} записать в файл, а потом из файла преобразовать в struct при чтении? чтобы int caloricity можно было пользоваться при вычеслении.
-
ivank
Re: Функция ограничения занятости памяти - С
Ginger
Если сойдёт бинарный вид, то fwrite(&data, sizeof(data), 1, out);
В общем, неправильный, но наименее требовательный к знаниям способ. Данные хранятся в файле data.dat
Добавление записи.
Код:
Удаление записи с заданным индексом index (индексация с единицы), с уплотнением.
Код:
Как считать, надеюсь понятно (хинт: fread, feof)
Если сойдёт бинарный вид, то fwrite(&data, sizeof(data), 1, out);
В общем, неправильный, но наименее требовательный к знаниям способ. Данные хранятся в файле data.dat
Добавление записи.
Код:
Код: Выделить всё
out = fopen("data.fat", "a");
fseek(out, 0, SEEK_END);
fwrite(&data, sizeof(data), 1, out);
fclose(out);Удаление записи с заданным индексом index (индексация с единицы), с уплотнением.
Код:
Код: Выделить всё
int n, i, desc;
out = fopen("data.fat", "a+");
fseek(out, 0, SEEK_END);
count = ftell(out) / sizeof(data);
for (i = index; i < n; ++i)
{
fseek(out, i*sizeof(data), SEEK_SET);
fread(&data, sizeof(data), 1, out);
fseek(out, (i-1)*sizeof(data), SEEK_SET);
fwrite(&data, sizeof(data), 1, out);
}
fclose(out);
// некошерно, и не уверен что будет стопудово работать:
// не люблю работу с дескрипторами вообще.
desc = _open("data.dat", _O_RDWR | _O_RANDOM);
_chsize(desc, sizeof(data)*(n-1));
_close(desc);Как считать, надеюсь понятно (хинт: fread, feof)