проблемы записи / чтения бинарных файлов - PullRequest
0 голосов
/ 17 мая 2010

Хорошо, у меня проблема с моим кодом для чтения двоичного файла ...

Сначала я покажу вам свой код написания:

void book_saving(char *file_name, struct BOOK *current)
{
    FILE *out;
    BOOK buf;

    out = fopen(file_name, "wb");

    if(out != NULL)
    {
        printf_s("Writting to file...");
        do
        {
            if(current != NULL)
            {
                strcpy(buf.catalog_number, current->catalog_number);
                strcpy(buf.author, current->author);
                buf.price = current->price;
                strcpy(buf.publisher, current->publisher);
                strcpy(buf.title, current->title);
                buf.price = current->year_published;
                fwrite(&buf, sizeof(BOOK), 1, out);
            }
            current = current->next;
        } while(current != NULL);

        printf_s("Done!\n");
        fclose(out);
    }
}

и вот моя "версия" для чтения:

int book_open(struct BOOK *current, char *file_name)
{
    FILE *in;
    BOOK buf;
    BOOK *vnext;
    int count;
    int i;

    in = fopen("west", "rb");
    printf_s("Reading database from %s...", file_name);
    if(!in)
    {
        printf_s("\nERROR!");
        return 1;
    }

    i = fread(&buf,sizeof(BOOK), 1, in);
    while(!feof(in))
    {
        if(current != NULL)
        {
            current = malloc(sizeof(BOOK));
            current->next = NULL;
        }

        strcpy(current->catalog_number, buf.catalog_number);
        strcpy(current->title, buf.title);
        strcpy(current->publisher, buf.publisher);
        current->price = buf.price;
        current->year_published = buf.year_published;
        fread(&buf, 1, sizeof(BOOK), in);

        while(current->next != NULL)
            current = current->next;

        fclose(in);

    }
    printf_s("Done!");

    return 0;
}

Мне просто нужно сохранить свой связанный список в двоичном файле и прочитать его обратно ... пожалуйста, помогите мне. Программа просто не читает его или его сбой каждый раз, когда возникает другая ситуация ...

Ответы [ 2 ]

2 голосов
/ 17 мая 2010
  1. Ваша петля do..while может быть сформирована лучше. Если вы собираетесь проверить в конце, не проверяйте и в начале. Если вы обнаружите, что должны это сделать, вы, вероятно, не используете правильный контроль потока. Например, здесь вы должны просто сказать while(current != NULL) { }

  2. Что вы пытаетесь сделать с if(current != NULL) { }? Вы устанавливаете текущий узел в вашем цикле на совершенно новый BOOK и делаете его следующим элементом NULL. Зачем? Почему бы просто не отразить цикл, который вы используете в методе записи?

  3. Посмотрите, что вы делаете, если current == NULL неявно - вы используете strcpy в своем методе чтения. Не делай этого.

  4. Вы, кажется, говорите fclose(in) в цикле while в book_open.

Я получу больше, как только скомпилирую.


Хорошо, я несколько отредактировал код, сделав 2 предположения

  1. Это не домашнее задание
  2. BOOK имеет только 1 указатель (next), а все остальное - массив с выделенной ему памятью

book_saving - просто зацикливается и пишет

FILE *out;
BOOK buf;

out = fopen(file_name, "wb");
if(out == NULL) return;

printf_s("Writing to file...");

while(current != NULL)
{
    fwrite(&buf, sizeof(BOOK), 1, out);
    current = current->next;
}

printf_s("Done!\n");
fclose(out);

book_open - переводит указатель на указатель на BOOK

int book_open(struct BOOK **current, char *file_name)
{
    FILE *in;
    BOOK *buf;  // a pointer with malloc'd memory - can't reuse the local variable version!
    BOOK *vnext = *current;
    int i;

    in = fopen("west", "rb");  // I hope that's the name of your file
    printf_s("Reading database from %s...", file_name);
    if(!in)
    {
        printf_s("\nERROR!");
        return 1;
    }

    while(1)
    {
        buf = malloc(sizeof(BOOK));
        i = fread(&buf,sizeof(BOOK), 1, in);
        if(feof(in))
        {
            free(buf); // never made it in
            break;
        }
        buf->next = NULL; // the 'next' written to file is certainly not the same

        // point current to it if empty, else point to next
        if(*current == NULL) *current = buf;
        else
        {
            wnext->next = buf;
            wnext = buf; // next iteration you'll be setting buf->next
        }
    }
    fclose(in);
    printf_s("Done!");

    return 0;
}

Я думаю, что лучше.

0 голосов
/ 17 мая 2010

Похоже, вы пытаетесь либо передать существующий список, который заполнен, либо, если он не был передан, тогда функция чтения пытается выделить и создать список. Ни одна ситуация не выглядит совершенно правильной.

Если это первый (передача в существующий список), то цикл while(current->next != NULL) будет сканировать до конца. Если вы пытаетесь создать новый список, то, похоже, нужно проделать дополнительную работу, чтобы связать новые узлы вместе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...