约束:不能将STL用于动态数组实现。
我已经暂时停留在这个问题上一段时间了,我对答案的研究还没有取得任何成果。任何帮助将不胜感激!
所以我试图编写一个程序,根据用户评价各种书籍的方式为用户提供建议。为了做到这一点,我需要能够读取包含作者和书名列表的.txt文件。 .txt的格式是"作者,书"每个条目都在自己的行上。
当我从.txt文件中读取时,我想用Book
类对象填充动态数组。因为这个项目不允许使用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
我对寻求帮助感到很难过,但我真的被困在这里了。提前谢谢。
答案 0 :(得分:1)
在DArray::add
内复制旧数组中的值时,检查i < (size - ONE)
,跳过最后一项,因为每次添加项时都会执行此操作,不会复制任何内容项目添加遗骸。