【问题标题】:Writing a Hash Table to File and Restoring From File in C++在 C++ 中将哈希表写入文件并从文件恢复
【发布时间】:2020-02-23 22:11:00
【问题描述】:

我正在使用结构程序中的哈希表为学校分配作业。部分任务是编写一个由 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;
            }
        }
    }
}

代码编译没有问题,但是当我检查文件时,我发现它只是乱码和奇怪的符号。我使用的数据以前是从另一个文件中提取的,我想以插入它的格式保存它。我确信问题出在 fwrite 的行上(我对 C 语法的经验不如 C++)。

数据在 DATAIN.dat 文件中,如下所示:

TATUNG CO.EL PR.加利福尼亚长滩 KAMERMAN LCIRRUS 比弗顿,或 QUADRAM COLOACH AV NORCROSS GE AST RESEARALTON AV IRVINE CA

我希望新文件看起来像这样:

大同公司 埃尔公关。加州长滩

卡默曼 L 卷云比弗顿,或

QUADRAM 公司 LOACH AV NORCROSS GE

AST 研究 奥尔顿 AV 欧文加州

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 尝试创建minimal reproducible example 并将其发布在您的问题中,而不是发布您的部分代码。确保问题可以重现。不要忘记写出您期望的输出。这样做可能会导致您找到解决方案。如果没有,edit你的问题,所以它变得可以回答。
  • 我应该添加原始文本文件吗?我还能做些什么来澄清?
  • 我需要包含我想要读取的文本文件吗?抱歉,我是这个网站的新手。
  • minimal reproducible example 表示,除其他外,“复制的最小示例”。您可以点击此链接阅读人们对您的示例的期望。我看到您添加了整个程序;它比部分好,但更好的是让你的例子最小化!想象人们想知道:“有问题的代码在哪里?是在InsertIntoHT 还是WriteHTtoDisk?” “最小”的想法是您使用消除方法自己回答这个问题(问题在哪里)。将您的代码减少到最低限度。在开始删除不相关的代码之前不要忘记进行备份。
  • 我想我已经把它减少到足以说明问题所在了。示例中的捆绑文本可以放入 .dat 文件并运行。我不确定如何附加全文文件。

标签: c++ hashtable


【解决方案1】:

您的代码似乎没有初始化,甚至没有使用成员count。当哈希桶为空时,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 类型,你可以避免使用幻数并写sizeof(STR10) 而不是11。这样,当您更改字符串的长度时,您的代码仍然可以工作。

【讨论】:

  • 它仍然给出同样的错误。当我在完整程序中运行带有编辑的代码时,它突然停止工作。
猜你喜欢
  • 2015-07-21
  • 1970-01-01
  • 2018-05-08
  • 2019-05-23
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
相关资源
最近更新 更多