填充动态类模板数组时遇到问题

Trouble filling a dynamic class template array

本文关键字:遇到 问题 数组 动态 填充      更新时间:2023-10-16

约束:不能使用STL实现动态数组

我在这个问题上已经纠结了一段时间了,我对答案的研究还没有取得任何成果。任何帮助将非常感激!

所以我在试着写一个程序,根据用户对各种书籍的评分方式为他们生成推荐。为了做到这一点,我需要能够读取包含作者和书名列表的.txt文件。txt的格式是"Author,Book",每个条目在自己的行上。

我想用Book类对象填充动态数组,因为我从.txt文件中读取。因为这个项目不允许使用STL,所以我需要编写自己的实现。

文件的处理正常,我可以使用cout.

在单独的行上显示每个条目的作者和图书

现在我被卡住了,试图用条目填充我的动态数组元素。我用来保存数据的类是Book,它包含一个数据成员的结构体。

我怀疑这个问题是我的函数在我的动态数组模板实现。

template<class Recommend>
void DArray<Recommend>::add(const Recommend &obj)

我最终想要使用这个模板来保存用户和评级的类对象。

现在我的代码似乎用适当数量的条目填充数组,但是除了最后一个元素之外,所有元素都填充了来自默认构造函数的Book对象。

相关代码如下:

P1.cpp:

//P1.cpp
#include "stdafx.h"
#include "Book.h"
#include "Member.h"
#include "Rating.h"
#include <iostream>
#include <fstream>

using namespace std;

void readBooks(string bookTxt)
{
    Book newBook;
    DArray<Book> bookArray;
    string line;
    ifstream file(bookTxt);
    if (file.is_open())
    {
        while (!(file.eof()))
        {
            getline(file, line, ',');
            newBook.bookData.author = line;
            getline(file, line, 'n');
            newBook.bookData.title = line;
            newBook.bookData.year = 2004; //Place holder
            newBook.setIsbn();
            bookArray.add(newBook);
        }
        for (int i = ZERO; i < 55; i++)
        {
            cout << bookArray[i].bookData.author << endl;
            cout << bookArray[i].bookData.title << endl;
            cout << bookArray[i].bookData.year << endl;
            cout << bookArray[i].bookData.isbn << endl;
        }

        file.close();
    }
    else cout << "Error: Unable to open file";
}
int main()
{
    readBooks("books.txt");
    int wait;
    cin >> wait;
    return 0;
} 

Book.h

//Book.h
#ifndef BOOK_H
#define BOOK_H
#include <string>
using namespace std;
const int ZERO = 0;
const int ONE = 1;
template<class Recommend>
class DArray
{
private:
    Recommend *array;
    int size;
    int bitSize;
public:
    DArray()
    {
        size = ZERO;
        array = new Recommend[ONE];
    }
    DArray(int initSize)
    {
        size = initSize;
        array = new Recommend[size];
    }
    ~DArray()
    {
        delete[] array;
    }
    DArray(const DArray &rhs);
    DArray &operator= (const DArray &rhs);
    DArray &operator= (const Recommend &rhs);
    Recommend& operator[] (int index);
    void add(const Recommend &obj);
    int getSize();
    void setSize(int size);
    void clear();
    void remove(int index);
    void* getPtr();
};
class Book
{
    //Generate a unique int for book ISBN
    int generateIsbn();

public:
    struct data
    {
        unsigned long int isbn;
        int year;
        string title, author;
    };
    data bookData;
    //Constructors (Default and Initializing)
    Book()
    {
        bookData.author = "";
        bookData.title = "";
        bookData.isbn = ZERO;
        bookData.year = ZERO;
    }
    Book(int initYear, string  initTitle, string initAuthor)
    {
        bookData.author = initAuthor;
        bookData.title = initTitle;
        bookData.year = initYear;
        bookData.isbn = generateIsbn();
    }
    //Book File IO Functions
    void loadFile(ifstream books) const;
    void saveFile(ofstream &books);
    //Mutator Functions
    void addBook(int addYear, string  addTitle, string addAuthor);
    void setIsbn();
    void setYear(data bookData);
    void setTitle(data bookData);
    void setAuthor(data bookData);
    //Accessor Functions
    Book getBook(data bookData) const;
    unsigned long int getIsbn() const;
    int getYear() const;
    string getTitle() const;
    string getAuthor() const;
};
template<class Recommend>
DArray<Recommend>::DArray(const DArray &rhs)
{
    size = rhs.size;
    array = new Recommend[size];
    for (int i = ZERO; i < size; i++)
        array[i] = rhs.array[i];
}
template<class Recommend>
Recommend& DArray<Recommend>::operator[] (int index)
{
    return array[index];
}
template<class Recommend>
DArray<Recommend>& DArray<Recommend>::operator= (const DArray &rhs)
{
    if (this == &rhs)
        return *this;
    //if (rhs.size == ZERO)
        //clear();
    setSize(rhs.size);
    for (int i = ZERO; i < size; i++)
        array[i] = rhs.array[i];
    return *this;
}
template<class Recommend>
DArray<Recommend>& DArray<Recommend>::operator= (const Recommend &rhs)
{
    if (this == &rhs)
        return *this;
    array[size] = rhs;
    return *this;
}
template<class Recommend>
int DArray<Recommend>::getSize()
{
    return size;
}
template<class Recommend>
void DArray<Recommend>::setSize(int resize)
{
    if (resize < 0)
    {
        Recommend *temp;
        temp = new Recommend(resize);
        for (int i = ZERO; i < resize; i++)
            temp[i] = array[i];
        delete[] array;
        array = temp;
        size = resize;
    }
    else
        clear();
}
template<class Recommend>
void DArray<Recommend>::add(const Recommend &obj)
{
    if (size == ZERO)
    {
        array[ZERO] = obj;
        size++;
    }
    else
    {
        int newSize = (size + ONE);
        Recommend *temp;
        temp = new Recommend[newSize];
        for (int i = ZERO; i < (size - ONE); i++)
            temp[i] = array[i];
        temp[(newSize - ONE)] = obj;
        delete[] array;
        size = newSize;
        array = temp;
    }
}
template<class Recommend>
void DArray<Recommend>::remove(int index)
{
    if (index <= ZERO)
    {
        if (size == ONE)
            clear();
        else
        {
            for (int i = index; i < (size - ONE); i++)
                array[i] = array[i + ONE];
            size--;
        }
    }
}
template<class Recommend>
void DArray<Recommend>::clear()
{
    delete[] array;
    size = 0;
}
template<class Recommend>
void* DArray<Recommend>::getPtr()
{
    return array;
}
#endif

Book.cpp:

//Book.cpp
#include "stdafx.h"
#include "Book.h"
const unsigned long int ISBN_MIN = 100000;
const unsigned long int ISBN_MAX = 999999;

//Generate a unique isbn
int Book::generateIsbn()
{
    unsigned long long int isbn;
    isbn = this->bookData.title.length();
    isbn += this->bookData.title.size();
    isbn += this->bookData.author.length();
    isbn += this->bookData.title.capacity();
    isbn += this->bookData.author.size();
    isbn += this->bookData.author.capacity();
    isbn *= this->bookData.year;

    isbn = isbn % ISBN_MAX + ISBN_MIN;
    isbn += this->bookData.author[ONE];
    isbn += this->bookData.title[ONE];
    isbn += this->bookData.author[ZERO];
    isbn += this->bookData.title[ZERO];
    static_cast<int>(isbn);
    return isbn;
}

void Book::addBook(int addYear, string  addTitle, string addAuthor)
{
    bookData.author = addAuthor;
    bookData.title = addTitle;
    bookData.year = addYear;
    bookData.isbn = generateIsbn();
}
unsigned long int Book::getIsbn() const
{
    return bookData.isbn;
}
void Book::setIsbn()
{
    this->bookData.isbn = generateIsbn();
}

book.txt示例

Neil Shusterman,The Shadow Club
Jeff Smith,Bone Series
Art Spiegelman,Maus: A Survivor's Tale
Amy Tan,The Joy Luck Club
J R R Tolkien,The Lord of the Rings
J R R Tolkien,The Hobbit
Eric Walters,Shattered
H G Wells,The War Of The Worlds
Patricia C. Wrede,Dealing with Dragons
John Wyndham,The Chrysalids

输出示例:

0  
0

0  
0

0  
0

0 
0  
John Wyndham  
The Chrysalids  
2004  
360893
我不好意思寻求帮助,但我真的被困在这里了。

DArray::add内部,当您从检查i < (size - ONE)的旧数组中复制值时,会跳过最后一项,因为每次添加项时都会这样做,因此不会复制任何内容,仅保留添加的最后一项