Запись таблицы Ha sh в файл и восстановление из файла в C ++ - PullRequest
1 голос
/ 24 февраля 2020

Я работаю над заданием для школы, используя таблицы ha sh в структурной программе. Частью назначения является запись таблицы ha sh, состоящей из 20 основных блоков и 10 блоков переполнения, каждый из которых имеет 3 слота, состоящих из поля ключа и данных, на диск и затем восстанавливается из него. Вот что у меня есть:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <string.h> // for strcpy()

using namespace std;

typedef char STR10[10+1];
typedef char STR20[20+1];

struct SLOT
{
  STR10 key;
  STR20 data;
};

struct BUCKET
{
  SLOT entry[3];
  int count;
  BUCKET* overflow;
};

struct HASHTABLE
{
  BUCKET pBkt[20];
  BUCKET oBkt[10];
};

void WriteHTtoDisk (HASHTABLE ht, char *HashDisk);
void ReportHT (HASHTABLE ht, char * when);

int main()
{
    int maxP = 20;
    int maxO = 10;
    int maxS = 3;
    HASHTABLE ht;

    STR10 mKey;
    STR20 mData;

    FILE * inFile;
    inFile = fopen("DATAIN.dat","rb");
    if (inFile == NULL)
    {
        cout << " DATAIN file access error ... \n";
        cout << " Terminating application ... \n ";
        cout << " Press any key ... \n ";
        return -100;
    }
    char crLF;

    while (!feof(inFile))
    {
        fscanf(inFile,"%10c%20c\n",mKey,mData);
        mKey[10] = mData[20] = 0; // add string terminators
        printf(" MyKey: %10s\n MyData: %20s\n",mKey,mData);
        cin.ignore(80,'\n'), cin.get();
        //InsertIntoHT (ht, mKey, mData);
    }

    fclose(inFile);

    WriteHTtoDisk(ht, "hashTable.dat");
    ReportHT (ht,"BEFORE");

    return 0;
}

void WriteHTtoDisk (HASHTABLE ht, char *HashDisk)
{
    FILE * HASHDISK = fopen(HashDisk, "rb");
    int maxBkt = 30;
    int maxSlot = 3;

    for (int i = 0; i < maxBkt; i++)
    {
        for (int j = 0; j < maxSlot; j++)
        {
            fwrite(ht.pBkt[i].entry[j].key,11,sizeof(maxSlot),HASHDISK);
            fwrite(ht.pBkt[i].entry[j].data,21,sizeof(maxSlot),HASHDISK);
        }

    }
}

void ReportHT (HASHTABLE ht, char * when)
{
    int maxB = 30;
    int maxS = 3;
    cout << "Hash Table \n" << "Verification Report \n" << when << " Restoration" << endl;

    for (int b = 0; b < maxB; b++)
    {
        cout << "Bucket " << (b+1) << endl;

        if (b < 20)
        {
            for (int i = 0; i < maxS; i++)
            {
                cout << setw(3) << "Slot " << (i+1) << ": " << ht.pBkt[b].entry[i].key << setw(3) << ht.pBkt[b].entry[i].data << endl;
            }
        }

        else
        {
            for (int i = 0; i < maxS; i++)
            {
                cout << setw(3) << "Slot " << (i+1) << ": " << ht.oBkt[b].entry[i].key << setw(3) << ht.oBkt[b].entry[i].data << endl;
            }
        }
    }
}

Код компилируется без проблем, но когда я проверяю файл, я обнаруживаю, что это всего лишь gibberi sh и странные символы. Данные, которые я использую, ранее были извлечены из другого файла, и я хочу сохранить их в том формате, в котором они были вставлены. Я уверен, что проблема связана со строками с fwrite (у меня нет такого опыта с синтаксисом C, как у меня с C ++).

Данные были в файле DATAIN.dat, например:

TATUNG CO.EL PR. Длинный пляж CA KAMERMAN LCIRRUS BEAVERTON, ИЛИ QUADRAM COLOACH AV NORCROSS GE AST RESEARALTON AV IRVINE CA

Я ожидаю, что новый файл будет выглядеть следующим образом:

TATUNG CO. EL PR. Длинный пляж CA

KAMERMAN L CIRRUS BEAVERTON, ИЛИ

QUADRAM CO LOACH AV NORCROSS GE

AST RESEAR ALTON AV IRVINE CA

Любая помощь будет очень полезна оценили. Спасибо.

1 Ответ

0 голосов
/ 24 февраля 2020

Похоже, ваш код не инициализирует и даже не использует элемент count. Когда ведро ha sh пусто, count должно указывать это. В C ++ это легко реализовать: просто добавьте = 0 к его определению:

struct BUCKET
{
  SLOT entry[3];
  int count = 0;
  BUCKET* overflow;
};

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

        for (int j = 0; j < ht.pBkt[i].count; j++)
            ...

Также пишите только необходимое количество байтов. fwrite принимает два параметра: размер записываемых элементов данных и их количество. Здесь размер равен 11 или 21, а число равно 1, поскольку каждый вызов fwrite может записать только одну строку в ваш файл.

            fwrite(ht.pBkt[i].entry[j].key,11,1,HASHDISK);
            fwrite(ht.pBkt[i].entry[j].data,21,1,HASHDISK);

Кстати, поскольку у вас есть STR10 введите, вы можете избежать волшебные числа c и написать sizeof(STR10) вместо 11. Таким образом, когда вы изменяете длину вашей строки, ваш код все равно будет работать.

...