|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Функция ограничения занятости памяти - С |
|
|
Функция ограничения занятости памяти - С
|
Рыжая Сообщения: 1550 |
Профиль | Сайт | Отправить PM | Цитировать Пишу прогу на С.
в неё входит создание маленькой БД. использую arrays of records and files как я не крутила так и не нашла способа не задавать явное колличество записей в БД. т.е. что бы файл растягивался как резиновый по мере поплнения бд или удаления из неё записей. подумала о том чтобы за ранее обозначить бОльшее число записей в array, допустим сразу 1000, и пополнять по мере необходимости. но тогда в памяти и будет занимать место для всей 1000 даже если там всего 10 записей. слышала есть спец. функция, которая ограничивает занятость памяти для array на колличество заполненных ентри. т.е. даже если арей на 1000, а занято всего 10, то память будет занимать только под 10. подскажите что за функция? желательно с синтаксисом, плз. [s]Исправлено: Ginger, 16:25 25-01-2004[/s] |
|
------- Отправлено: 16:05, 25-01-2004 |
Рыжая Сообщения: 1550
|
Профиль | Сайт | Отправить PM | Цитировать нашла, кажется, выход с безразмерными structures:
#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); } а это что такое - 1,f); ? [s]Исправлено: Ginger, 18:24 25-01-2004[/s] |
------- Отправлено: 18:23, 25-01-2004 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Ginger
Причём тут безразмерные структуры не ясно. Обычный RANDOM access к файлу. Если всё хранится в файле, то вполне подойдёт связка fseek/ftell. Если надо запись надо удалить, то просто помечаешь её как удалённую (т.к. сдвигать все последующие слишком долго). И изредка сжимаешь БД сдвигая все записи на места удалённых. Так работают некоторые dbm-базы. Правда, там ещё поле-ключ поддерживается, но это детали. Там просто балансируемое при доступе дерево с ключами в начале файла в простейшем случае сойдёт. На счёт fwrite: Цитата:
RANDOM д.б. написано маленькими буквами, а безразмерных структур вообще не существует. |
|
------- Отправлено: 20:17, 25-01-2004 | #3 |
Рыжая Сообщения: 1550
|
Профиль | Сайт | Отправить PM | Цитировать говоря о размере я имела ввиду функцию - sizeof()
о fwrite() спросила, потому что не знаю синтаксиса, а не потому что считаю, что она как-то на размер файла влияет и это всё не главное. мой главный вопрос в первом посте: Цитата:
Цитата:
|
||
------- Отправлено: 22:03, 25-01-2004 | #4 |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Какое имеет отношение sizeof к безразмерности не ясно.
Начнём с простого вопроса: хранится вся информация в файле или в памяти? В оригинальном посте это не очевидно (мне во всяком случае). А так же, храниться должно всё именно как массив (т.е. в программе присутствует доступ по индексу) или как угодно/удобно? Если в файле, то см. предыдущий мой ответ. Т.е. надо курить доументацию поблочному вводу выводу, а так же ф-иям установки/чтения позиции в файле. Весь необходимый арсенал ф-ий в этом случае: fopen, fclose, fwrite, freed, fseek, ftell. Далее, если мы пользуем C++ и всё хранится в памяти, то вполне подойдёт stdd:vector/std::deque (в случае массива) или std::list (если присутствует только последовательный доступ к элементам). Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc. Ну и от связных списков и более нетривиальных структур, реализованных ручками тоже никто отказываться не собирается. В общем, если чуть поточнее будут поставлены условия, то любой из этих способов можно будет рассмотреть поподробнее. |
|
------- Отправлено: 23:24, 25-01-2004 | #5 |
Рыжая Сообщения: 1550
|
Профиль | Сайт | Отправить PM | Цитировать ivank
вобщем прога вычесляет коллории. при этом она хранит данные в нескольких файлах, которые представляют собой отдельные категории - мясо, хлеб, овощи, фрукты. в каждой категории хранятся данные (имя продукта и его каллорийность) неограниченного чилса продуктов. т.к. нужно чтобы юзер мог и добавить новый продукт в конкретную категорию и удалить, и править. при этом имя продукта - чар каллорийность - инт потому что каллорийность будет использоваться в вычеслениях. так вот я и думаю, как это дело организовать по умному. Цитата:
я тут порылась и придумала приблизительно такой выход: для каждой категории заводим отдельный файл имя продукта и его каллорийность записываем через строку, т.е: белый хлеб 226 чёрный хлеб 214 ... когда нам нужно мы находим (юзер будет вводить имя продукта, а прога находить его каллорийность и вычеслять что там надо) каллорийность переводим его из чар в инт (т.к. я не знаю как хранить каллорийность как инт): callor=(int)value_of_caloricity (вроде так можно) и делаем вычесления. конечно был ещё "выход": создать struct { char name[40]; int caloricity;} для каждой категории.. при этом записей должно быть какое-то колличество, т.е. arrays of records вот я с самого начала и спросила - есть ли функция ограничения занятости памяти до заполненного коллическва ентриес в аррей... но это ещё ладно, а вот как это дело запихать в файл и как потом от туда так же считать... я не знаю... [s]Исправлено: Ginger, 0:38 26-01-2004[/s] |
|
------- Отправлено: 23:54, 25-01-2004 | #6 |
Рыжая Сообщения: 1550
|
Профиль | Сайт | Отправить PM | Цитировать ну обьясните хотя бы как struct Vegetables { char name[40]; int caloricity;} записать в файл, а потом из файла преобразовать в struct при чтении? чтобы int caloricity можно было пользоваться при вычеслении.
|
------- Отправлено: 16:58, 26-01-2004 | #7 |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Ginger
Если сойдёт бинарный вид, то 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); 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); |
------- Отправлено: 18:32, 26-01-2004 | #8 |
Рыжая Сообщения: 1550
|
Профиль | Сайт | Отправить PM | Цитировать ivank
вобщем в твоём примере я мало чего поняла... но нашла хорошую книжку, где чуть ли не каждая буковка расталковывается, там прочитала о нужных мне функциях и вот что получилось (без malloc(), fseek(), ftell() etc...) #include <stdio.h> /* Proga pishit i chitaet dlia odnogo kataloga */ #define FALSE 0 #define TRUE !FALSE struct vegetables { char name[40]; int caloricity; }veg; void write_info(void); void read_info(void); int main(void) { char c; int done=FALSE; while(!done) { puts("\n ***:: Vegatables Catalogue ::***\n"); puts(" A - Add new entry\n"); puts(" L - List entries\n"); puts(" Q - Quit\n"); printf(" Your choice is: "); c = getch(); c = tolower(c); switch(c) { case('a'): puts(" Add new entry\n"); write_info(); break; case('l'): puts(" List all entries\n"); read_info(); break; case('q'): puts(" Quit\n"); done=TRUE; break; default: puts(" Incorrect letter. Try again."); done=FALSE; break; } } } void write_info(void) { FILE *veget; int calor; printf("Enter product name: "); gets(veg.name); printf("Enter its caloricity per 100g: "); veg.caloricity = scanf("%i",&calor); veget = fopen("G:/Studies/Project/programm/vegetables.dat", "a"); if(!veget) { puts("Error openning file"); exit(1); } else { fwrite(&veg,sizeof(veg),1,veget); } fclose(veget); puts("Entry added"); } void read_info(void) { FILE *veget; int x; veget = fopen("G:/Studies/Project/programm/vegetables.dat", "r"); if(!veget) { puts("Error reading file"); return; } else { while(TRUE) { x=fread(&veg,sizeof(veg),1,veget); if(!x) break; printf("\nProduct Name: %s\n",veg.name); printf("Its caloricity: %i\n",veg.caloricity); } } fclose(veget); } |
------- Отправлено: 21:19, 28-01-2004 | #9 |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Ginger
В общем-то добавление и чтение сделаны как я и сказал А удаления нет вообще. Кстати, ещё более простой метод удаления, я о нём забыл в предыдущий раз сказать, хотя хотел: открываем файл с данными для чтения, и временный для записи. Затем в цикле копируем все записи кроме той, которую надо удалить, из исходного файла во временный. Закрываем оба файла, и таким же маром копируем всё из временного в файл с данными. Дёшево и сердито. Добавлено: Цитата:
|
|
------- Отправлено: 01:30, 29-01-2004 | #10 |
|
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Функция - SLI !!! | Ironhammer | Видеокарты | 2 | 22-09-2008 05:32 | |
Outlook 2000 + Exchange 2003, ошибка "не удается обновить данные о занятости" | mleck | Microsoft Exchange Server | 0 | 08-02-2007 13:31 | |
Функция ClearType | destrier | Microsoft Windows 2000/XP | 2 | 18-11-2006 21:11 | |
Массив и функция | Scorpion666 | Вебмастеру | 4 | 02-03-2006 12:44 | |
Функция ReadFile | DillerInc | Программирование и базы данных | 8 | 18-07-2005 07:45 |
|