|
|
|
| пожалуйста, не переносите тему, т.к форум С++ не посещаем...
в общем привожу кусок кода:
// структура
struct goods
{
// партнамбер
// уникальный для каждого товара
char pn[10];
// название товара
char name[30];
// цена
int price;
// количество
int kol;
} prod;
// вырезка из функции
if ((tf=fopen("product/file1.dat","rb+")) != NULL)
{
printf(" Enter part number: ");
gets(goods);
fread(&prod,sizeof(prod),1,tf);
while (!feof(tf))
{
if (strcmp(prod.pn,goods)==0)
{
// каким образом можно удалить из файла текущую запись?
break;
}
fread(&prod,sizeof(prod),1,tf);
}
fclose(tf);
}
|
| |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 10:17)
| | файл это не база данных, "просто удалить" касательно файла имеет примерно следующий алгоритм:
* найти удаляемый кусок,
* прочитать оставшийся файл до конца,
* записать поверх удаляемого куска.
Если удаляются несколько записей, то проще в озу сформировать данные для файла, и потом его переписать полностью | |
|
|
|
|
|
|
|
для: Волки
(20.10.2009 в 10:22)
| | запись удаляется только одна, я уже и так и так пробовал...но как говорится - "как-то не удалось". поэтому пошёл на крайности и начал флудить на этом форуме. примерчик какой-нибудь не подкините? гугл мне не помог... | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 10:28)
| | Зависит от организации данных внутри файла.
Например, можно прочитать из файла последнюю запись, записать её на место удаляемой, после чего укоротить файл по позиции начала последней записи.
fread, fwrite, fseek, ftell, ftruncate | |
|
|
|
|
|
|
|
для: Trianon
(20.10.2009 в 10:35)
| | извиняюсь, не увидел вашего сообщения.
начало понятно, только объясните плиз смысл и как реализуется вот это:
>после чего укоротить файл по позиции начала последней записи
? | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 14:10)
| | >извиняюсь, не увидел вашего сообщения.
Модератора благодарите. :)
>начало понятно, только объясните плиз смысл и как реализуется вот это:
>>после чего укоротить файл по позиции начала последней записи
>?
если запись из файла удалена, значит файл должен стать на одну запись короче, так?
Это смысл.
А реализация... переносимой реализации некоторое время назад не было... Возможно, нету и сейчас. Тут надо смотреть инструментарий выбранной среды исполнения. То есть набор функций работы с файлами, которым можно пользоваться.
http://www.google.ru/search?hl=ru&q=ftruncate | |
|
|
|
|
|
|
|
для: Trianon
(20.10.2009 в 17:14)
| | >Модератора благодарите. :)
а я думал это я слепой, и что Вы ничего не предложили а решили поиздеваться :)
>если запись из файла удалена, значит файл должен стать на одну запись короче, так?
согласен
но это всё барахло делаю в borland c++ 3.1, и в Help'е не вижу такой функции и соответвенно не понимаю как её юзать. в гугле пока тоже ничего не нарыл...
такое чувство что придется заходить с другой стороны :(
просто сначала хотелось как можно проще и грамотнее реализовать. тот вариант что написал Волки я вообще не понял. | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 17:32)
| | прочитал на одном форуме:
>А по старинке файл срезали записью в него 0 байт. Ну, т.е. lseek(где_резать); write(file, buf, 0);
скажите, такое пройдет? | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 17:43)
| | а, всё, нашёл, функция chsize :)
буду пытаться :)
в любом случае - спасибо Вам за идею | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 17:50)
| | уря! посидел сегодня полчаса и сделал!
// размер строки структуры
s = sizeof(prod);
// переходим на начало строки
fseek(tf,-s,1);
// сохраняем текущее значение указателя
curpos = ftell(tf);
// переходим в конец файла
fseek(tf, 0L, SEEK_END);
// переходим на начало последней строки
fseek(tf,-s,1);
// считываем последнюю запись
fread(&savezap, s, 1, tf);
// возвращаем указатель на перезаписываемую запись
fseek(tf, curpos, SEEK_SET);
// записываем последнюю запись на место удаляемой
fwrite(&savezap[0], s, 1, tf);
// дескриптор файла
handle = fileno(tf);
// размер файла
fs = filelength(handle);
// обрезаем последнюю запись
chsize(handle,fs-s);
|
всё было как бы не так и сложно :)
огромное спасибо Trianon-у! | |
|
|
|
|
|
|
|
для: Волки
(20.10.2009 в 10:22)
| | >Если удаляются несколько записей, то проще в озу сформировать данные для файла, и потом его переписать полностью
Это , блин, ни разу не проще, чтоб не сказать - невозможно.
В контексте любых нормальных исполняющих сред предполагается, что объем данных в файле всяко в оперативную память не полезет. | |
|
|
|
|
|
|
|
для: Trianon
(20.10.2009 в 10:34)
| | у меня это не актульно...нужно просто сдать курсовой
>* найти удаляемый кусок,
>* прочитать оставшийся файл до конца,
>* записать поверх удаляемого куска.
вот этот вариант мне подходит. но пока не получается реализовать | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 10:36)
| | строго не судите, уже год на С не програмил, позабылось немного,
и нужно будет в отладчике все это естественно продебажить
function killGoodById (int id) {
FILE file = fopen("product/file1.dat","rb+");
char strId[10];
sprintf (strId, "%d", id);
if (file == NULL) return NULL;
prod *oneGoods = new prod;
while (!eof(file)) {
fread(oneGoods, sizeof(prod), 1, file);
if ( strcmp(strId, oneGoods->pn)==0)
{
// найден нужный элемент, удалим
fseek(file, 0L, SEEK_END);
int size = ftell (file);
fseek (file, 0, SEEK_SET);
size -= ftell(file); //размер оставшегося файла
char *buffer = new char[ size ];
fread (buffer, size, 1, file);
fseek (file, -sizeof(prod), SEEK_SET);
fwrite (buffer, size, 1, file);
delete buffer;
break;
}
}
fclose(file);
delete oneGoods;
}
|
| |
|
|
|
|
|
|
|
для: Волки
(20.10.2009 в 11:54)
| | не совсем понял как вызвать функцию из программы, точнее что в неё передать... | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 12:08)
| | а если такой вариант
................
if (strcmp(prod.pn,goods)==0)
{
// получаем текущую позицию в файле
int pos = ftell(tf);
}
.................
|
можно ли считать файл с этой позиции и скажем запихнуть в перменную и записать с помощью fwrite с этой позиции?? | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 12:12)
| | > записать с помощью fwrite с этой позиции
с этой позиции нельзя, т.к. считав информацию про конкретный товар - указатель передвинулся, и надо вернуть назад на "размер товара"
а внутрь функции передается идентификатор удаляемой записи.
и кстати, у вас структура выравнена по границе 8 байт? | |
|
|
|
|
|
|
|
для: Волки
(20.10.2009 в 12:39)
| | >и кстати, у вас структура выравнена по границе 8 байт?
на этот вопрос у меня нет ответа т.к я не понял о чём Вы :(
указатель вот так получается возвратить обратно:
fseek(tf,-sizeof(prod),1);
|
так можно ли в таком случае записать переместив? | |
|
|
|
|
|
|
|
для: psychomc
(20.10.2009 в 12:46)
| | sizeof (prod) = 48 байт, что кратно 8 .
> так можно ли в таком случае записать переместив?
Да, думаю можно, пробовать надо, дебугером. | |
|
|
|
|
|
|
|
для: Волки
(20.10.2009 в 13:23)
| | никак не могу считать файл полностью с этой позиции | |
|
|
|