Удаление элемента из двоичного файла с++

170
01 апреля 2018, 20:38

Имеется однонаправлянный связаный список, который находиться в двоичном файле. Файл мы создает из консоли, и там же его заполняем. Проблема возникает, когда я пытаюсь удалить единственный элемент из списка, со всеми остальными работает отлично. Вот две функции по удалению, пока временное решение - удалить и создать файл заново.

void delEl(FILE *&f, int &Start, char key[], char fname[15]){
TBook wp,pp;
int iwp = Start,ipp = -1;
    while(iwp != -1)
    {
        fseek(f,iwp,SEEK_SET);
        fread(&wp,sizeof(TBook),1,f);
        if(strcmp(key,wp.name) == 0) break;
        pp = wp;
        ipp = iwp;
        iwp = wp.Next;
    }
    if(ipp == -1 && wp.Next == -1){
        fclose(f);
        remove(fname);
        openFile(fileName,Start);
    }
    else if(ipp == -1){
        pp = wp;
        ipp = iwp;
        iwp = wp.Next;
        fseek(f,iwp,SEEK_SET);
        fread(&wp,sizeof(TBook),1,f);
        fseek(f,ipp,SEEK_SET);
        fwrite(&wp,sizeof(TBook),1,f);
        deleteFromFile(f,iwp);
    }
    else{ pp.Next = wp.Next;
    fseek(f,ipp,SEEK_SET);
    fwrite(&pp,sizeof(TBook),1,f);
    deleteFromFile(f,iwp);//Освобождение физического места в файле после удаления элемента из списка

}}

void deleteFromFile(FILE *&f,int delPos){
TBook book;
// читаем заголовок списка дыр из файла
  rewind(f);
  fread(&book,sizeof(TBook),1,f);
    // в прочитанном заголовке в поле Next  находится адрес первой дыры
    // теперь эта дыра будет второй, значит то, что записано в поле Next
    // заголовочной записи, записываем в поле next новой дыры, теперь она
    // первая. Надписываем не отдельно значение поля Next, а полностью
    //запись, так как информация в дырах для нас не важна
  fseek(f,delPos,SEEK_SET);
  fwrite(&book,sizeof(TBook),1,f);
    // Изменяем поле Next заголовочной записи, теперь в нем адрес вновь
    //добавленной дыры
  book.Next=delPos;
  rewind(f);
  fwrite(&book,sizeof(TBook),1,f);}
Answer 1

Я немного изменю часть кода, где по моему логика неправильная:

if(ipp == -1 ){
    if (wp.Next == -1) {
        fclose(f);
        remove(fname);
        openFile(fileName,Start);
    }
    else {
        pp = wp;
        ipp = iwp;
        iwp = wp.Next;
        fseek(f,iwp,SEEK_SET);
        fread(&wp,sizeof(TBook),1,f);
        fseek(f,ipp,SEEK_SET);
        fwrite(&wp,sizeof(TBook),1,f);
        deleteFromFile(f,iwp);
    }
}
else{...
READ ALSO
Найти угол между тремя точками

Найти угол между тремя точками

Необходимо определить угол точки C относительно двух точек А и В, точки A и B образуют "отрезок", который можно ассоциировать с осью X, так как...

213
Почему крашится программа?

Почему крашится программа?

Она вообще компилироваться не должна - ну нет в C++ массивов с размером, известным во время выполнения

208
Как включить в итоговый APK пакет lib/armeabi-v7a?

Как включить в итоговый APK пакет lib/armeabi-v7a?

У меня есть проект на JavaПосле комплиляции и сборки APK должен содержать в себе пакет lib/armeabi-v7a с

234
“JAVA” Нужно отправить get запрос и взять json

“JAVA” Нужно отправить get запрос и взять json

Нужно отправить GET запрос, не принципиально как и взять с сервера ответ в виде JSONИли можно просто из stringbuffer сделать JSON

223