如何从文件中检索链表(在 Turbo C++ 中)

How do I retrieve a linked list from a file (in Turbo C++)

我已经在我的学校 CS 项目上工作了几个星期,我编写了一个基于文本的程序来管理 C++ 中的 supermarket/shop。我 运行 在尝试存储数据库并从文件存储中读取它时遇到了一些麻烦。

完整来源here

我知道 TurboC++ 是一个非常过时的编译器,但它是我规定的教学大纲的一部分,所以没有办法摆脱它。 (谢天谢地,下一批出来会学习python)

我的主要概念是使用自引用结构作为由 class 及其函数处理的单向链表的节点。

struct product  //Self referencial structure to store the product details
{
    unsigned int code;
    char name[100];
    char category[40];
    unsigned int quantity;
    double price;
    product *next;
};
class list  //Class to handle the linked list of products
{
    private:
        product *head, *tail;
    public:
        list()
        {
            head = NULL;    //By default the list will be empty
            tail = NULL;
        }
        void DelList(); 
        void AppProduct(product *, unsigned int);
        void AddProduct(unsigned int);  
        product* FindProduct(unsigned int); 
        double CalcTotal();
        void ListProducts();    
        void ModProduct(product *);
        void SaveToFile();
        void LoadFromFile();
        product* PointToNewProduct(product);
        product* GetProductFromFile(ifstream &);
        product* GetHead()
        {
            return head;
        }
        void Clear();
};

storecart是全局声明的objects of class list存储单独的链表。

我主要是为程序选择了链表格式,后来发现文件处理是项目的必修部分后才决定添加保存到文件和从文件加载。这是我为相同的代码编写的 -

void list::SaveToFile()     //self explanatory
{
    ofstream fout("DATABASE.DAT", ios::trunc);
    product * cur = head;
    product temp;
    while( cur != NULL )
    {
        temp = *cur;
        fout.write( (char *)&temp, sizeof(product) );
        cur = cur->next;
    }
    fout.close();
}
product * list::PointToNewProduct(product temp)     //copy the temp product details into a new pointer and return the pointer
{
    product * cur = new product;
    cur->code = temp.code;
    strcpy(cur->name, temp.name);
    strcpy(cur->category, temp.category);
    cur->price = temp.price;
    cur->quantity = temp.quantity;
    cur->next = NULL;
    return cur;
}

product * list::GetProductFromFile(ifstream& fin)       //retrieve a single product from the given file
{
    if( fin.eof() )
        return NULL;
    product temp;
    fin.read( (char *)&temp, sizeof(product) );
    cout<<temp.name;
    return PointToNewProduct(temp);
}
void list::LoadFromFile()       //Function to load struct from file and rebuild the linked list (only returning one item right now)
This is the code I wrote for the same -     //Update: I thought I fixed it, but its up to two items now, still not all
{
    ifstream fin("DATABASE.DAT", ios::in);      //Initialize the stream
    head = GetProductFromFile(fin);     //initialize head pointer
    product * cur = head;       
    product * nextptr;
    do {
        nextptr = GetProductFromFile(fin);      //get the next product in file
        cur = cur->next = nextptr;      //link product with the previous product
        tail = cur;     //make the current pointer the last one
    } while( !fin.eof() );
    tail->next = NULL;
    fin.close();
}

现在我的问题是,虽然我能够正确地将链表项写入文件,但尝试读取它会导致它只检索 2 个节点,而不管我写入文件的节点数量是多少。

和我老师的调试session让我相信这是因为我在从文件加载一个链表时没有删除旧的链表,而这个未释放内存的问题在写入文件时继续存在.我编写的用于释放内存的析构函数从未被调用,因为我的 objects 是全局声明的,导致我编写 DelList(); 函数并在从文件读取之前调用它。不幸的是,这并没有解决问题。

void list::DelList()
        {
            product * cur = head, * temp;
            while(cur != NULL)
            {
                temp = cur;
                cur = cur->next;
                delete temp;
            }
            delete cur;
            delete head;
            delete tail;
            head = NULL;
            tail = NULL;
        }

这是我为此编写的代码 - 我还添加了一些测试代码作为 switchcase 选择,我只是在没有链接的情况下从文件中读取,它也没有显示所需的输出。

case 7:
                    clrscr();
                    ifstream fin("DATABASE.DAT", ios::in);  
                    product temp;
                    fin.seekg(0, ios::beg);
                    while( fin.read( (char *)&temp, sizeof(product) ) )
                    {
                        //fin.read( (char *)&temp, sizeof(product) );
                        cout<<temp.name<<'\t'<<temp.category<<'\n';
                    }
                    getch();
                    break;

我的代码有什么问题,我该如何解决?

我设法通过变通方法解决了我的问题,但我仍然不知道为什么我的原始代码不起作用,尽管问题似乎出在文件的读写指针上。

我为解决此问题所做的工作是将 product 更改为 class,继承自基础 class prod,其中 prod 包含与结构相同的内容,但指向下一个的指针除外。然后我写了一个函数 Delink() 将 linked 列表中的每个 product 转换为 prod 并将其写入文件。 然后在读取文件时,我将读取的每个 prod 转换为 product 并将其 link 返回以再次构建 linked 列表。这似乎解决了我的问题。