Trouble filling a dynamic class template array - c++

Constraints: Cannot use STL for dynamic array implementation.
I've been stuck on this problem for a while now and my research into the answer hasn't yielded anything fruitful yet. Any help would be greatly appreciated!
So I'm trying to write a program that will generate recommendations to users based on the way they have rated various books. In order to do that I need to be able to read in a .txt file that contains a list of authors and titles of books. The format of the .txt is "Author,Book" with each entry on its own line.
I want to fill a dynamic array with Book class objects as I read from the .txt file. Because STL is not allowed for this project, I needed to write my own implementation.
The processing of the file went alright, I was able to display the author and book of each entry on separate lines using cout.
Now I am stuck trying to fill my dynamic array elements with the entries. My class to hold the data is Book and contains a struct of data members.
I am suspicious that the problem is with my function in my dynamic array template implementation.
template<class Recommend>
void DArray<Recommend>::add(const Recommend &obj)
I will eventually want to use this template to hold class objects for users and ratings.
Right now my code appears to fill the array with the proper number of entries, but all but the last element are fill with what looks like Book objects from the default constructor.
Here is the relevant code:
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();
}
A sample of 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
Sample of the output:
0
0
0
0
0
0
0
0
John Wyndham
The Chrysalids
2004
360893
I feel bad about asking for help, but I'm really stuck here. Thank you in advance.

Inside DArray::add when you copy the values from the old array you check for i < (size - ONE), that skips the last item, since you do it each time you add an item nothing gets copied and only the last item added remains.

Related

I have a weird segmentation fault, std::length_error and sometimes my code works?

I finished some code that prints out how many times a word shows up. However, when I finished and tried to run the code on a different compiler it did not work. Firstly, here is a picture of my code working on my initial file:
But when I used a different compiler (onlinegdb) I get this error:
The thing that confused me the most is; when I try and replicate the file into a new VS Code .cpp file, it does not work. It runs the code but then prints out nothing. When I went into gdb I find this error:
If anyone knows where the segmentation fault/std::length_error are happening at please let me know, and if you have any recommendations that would be great! Also, knowing why I get different results on the same compiler (VS Code) would also be helpful. Here is my code:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
class WordOccurrence
{
public:
WordOccurrence(const string& word="", int num=1)
{
word_ = word;
num_ = num;
}
bool matchWord(const string & compare)
{
if(word_ == compare)
return true;
else
return false;
}
void increment()
{
num_++;
}
string getWord() const
{
return word_;
}
int getNum() const
{
return num_;
}
private:
string word_;
int num_;
};
class WordList
{
public:
friend bool equal(const WordList&, const WordList&);
WordList();
WordList(const WordList &);
~WordList();
WordList operator= (const WordList &);
void addWordFile(WordList w);
void addWord(const string &);
void print();
private:
WordOccurrence *wordArray_;
int size_;
};
WordList::WordList()
{
size_ = 0;
wordArray_ = new WordOccurrence [size_];
}
WordList::WordList (const WordList &neww)
{
size_ = neww.size_;
wordArray_ = new WordOccurrence[size_];
for (int i = 0; i <= (size_ - 1); i++)
wordArray_[i] = neww.wordArray_[i];
}
WordList::~WordList ()
{
delete [] wordArray_;
}
WordList WordList::operator= (WordList const &overload)
{
WordList temp(overload);
swap(wordArray_, temp.wordArray_);
swap(size_, temp.size_);
return *this;
}
void WordList::addWord(const string& word)
{
if(size_ == 0)
{
WordOccurrence *first_array = new WordOccurrence[1];
first_array[0] = word;
delete[] wordArray_;
wordArray_ = first_array;
delete[] first_array;
size_++;
return;
}
//if the word is already in the array, we increase the count of it by 1
for (int i = 0; i < size_; i++)
{
if (wordArray_[i].matchWord(word))
{
wordArray_[i].increment();
return;
}
}
//if it is not in the array already, we need to increase its size and then add the new word to the wordarray.
WordOccurrence *new_array = new WordOccurrence[size_+1];
for (int i = 0; i < size_; i++)
{
new_array[i] = wordArray_[i];
}
new_array[size_] = WordOccurrence(word);
delete[] wordArray_;
size_++;
wordArray_ = new_array;
delete[] new_array;
}
void WordList::print()
{
//to output to a file because when we get a lot of words it's kinda hard to see on just the terminal
ofstream myfile ("output.txt");
WordList sortedList(*this);
//Sorting from smallest to largest
int smallest = wordArray_[0].getNum();
for (int i = 1; i < size_; i++)
{
//stores the smallest value into smallest
if(wordArray_[i].getNum() < smallest)
smallest = wordArray_[i].getNum();
}
int location = 0;
//stores values from start to finish in the new list starting at location sortedList[0]
while(location < size_)
{
for(int i = 0; i < size_; i++)
{
//runs through the new list until it finds a value that is apart of the smallest/rarest words
if(wordArray_[i].getNum() == smallest)
{
sortedList.wordArray_[location] = wordArray_[i];
location++;
}
}
//increases the value of smallest allowing for numbers with greater found values to be sorted
smallest++;
}
//prints out the sorted version of wordarray
for(int i = 0; i < size_; i++)
{
string word = sortedList.wordArray_[i].getWord();
int count = sortedList.wordArray_[i].getNum();
cout << "Word: " << word << " Amount: " << count << endl;
//for longer amounts of text, it was hard to see on a editor so I also have it out to a file.
myfile << "Word: " << word << " Amount: " << count << endl;
}
}
int main()
{
WordList w;
w.addWord("one");
w.addWord("one");
w.addWord("two");
w.addWord("three");
w.addWord("four");
w.addWord("four");
w.addWord("four");
w.addWord("four");
w.addWord("five");
w.addWord("five");
w.addWord("five");
cout << "Sorted list" << endl;
w.print();
}
This is bugged
WordOccurrence *first_array = new WordOccurrence[1];
first_array[0] = word;
delete[] wordArray_;
wordArray_ = first_array;
delete[] first_array;
size_++;
return;
You assign first_array to wordArray_ and then you delete it. This leaves wordArray_ as an invalid pointer. Just remove delete[] first_array;. Two deletes and only one new should have been a clue that something was wrong.
Same bug later on in the same function
WordOccurrence *new_array = new WordOccurrence[size_+1];
for (int i = 0; i < size_; i++)
{
new_array[i] = wordArray_[i];
}
new_array[size_] = WordOccurrence(word);
delete[] wordArray_;
size_++;
wordArray_ = new_array;
delete[] new_array;
delete[] new_array; should not be there.

Hash table doesn't read last line off of test file

I was assigned to create a chained hash table using a vector of vectors. It is designed to hold objects of type Entry. I have written all of the functions and the constructor but when I try to use the constructor that reads an input and then output it back to me in order of keys, whichever string was on the last line of the .txt file its reading from is gone. I think its a problem with my constructor because when I try to use get to get that specific value from the table before printing it its gone. I was hoping for some insight to where I might be going wrong from someone with a little more experience. Thanks. Heres my code:
Entry Header File:
#ifndef entry_h
#define entry_h
// entry.h - defines class Entry
#include <string>
#include <iosfwd>
class Entry {
public:
// constructor
Entry(unsigned int key = 0, std::string data = "");
// access and mutator functions
unsigned int get_key() const;
std::string get_data() const;
static unsigned int access_count();
void set_key(unsigned int k);
void set_data(std::string d);
// operator conversion function simplifies comparisons
operator unsigned int () const;
// input and output friends
friend std::istream& operator>>
(std::istream& inp, Entry &e);
friend std::ostream& operator<<
(std::ostream& out, Entry &e);
private:
unsigned int key;
std::string data;
static unsigned int accesses;
};
#endif /* entry_h */
Table header file:
//
// table.h
//
//
#ifndef table_h
#define table_h
#include <string>
#include <vector>
#include <algorithm>
#include "entry.h"
using namespace std;
class Table {
public:
Table(unsigned int max_entries = 100);
//Builds empty table to hold 100 entries
Table(unsigned int entries, std::istream& input);
//Builds table to hold entries, reads and puts them 1 at a time
~Table();
//Destructor
void put(unsigned int key, std::string data);
//Creates new entry for the table
//Updates if key is used
void put(Entry e);
//Creates a copy of e in the table
string get(unsigned int key) const;
//Returns string associated with key
//Returns empty string if key isnt used
bool remove(unsigned int key);
//Removes entry in given key
//Returns true of removed, false of no entry
int find(Entry e);
//index in second array that e exists, 0 if not found
friend std::ostream& operator<< (std::ostream& out, const Table& t);
//Prints each entry in the table in order of their key
private:
int size;
int num_entries;
unsigned int hashkey(unsigned int key) const;
vector<vector<Entry> > A;
};
#endif /* table_h */
Table Implementation File:
//table.cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include "table.h"
using namespace std;
Table::Table(unsigned int max_entries){
max_entries = 100;
size = max_entries * 2;
A.resize(size);
}
Table::Table(unsigned int entries, std::istream& input){
size = entries*2;
A.resize(size);
num_entries = entries;
Entry temp;
for (size_t i = 0; i < entries; i++) {
input >> temp;
put(temp);
}
}
Table::~Table() {
A.clear();
}
void Table::put(unsigned int key, std::string data){
Entry e;
e.set_key(key);
e.set_data(data);
put(e);
num_entries++;
}
void Table::put(Entry e) {
if (A[hashkey(e.get_key())].empty()) {
A[hashkey(e.get_key())].push_back(e);
}
else {
for(size_t i = 0; i < A[hashkey(e.get_key())].size(); i++) {
if (A[hashkey(e.get_key())][i].get_key() == e.get_key()) {
remove(A[hashkey(e.get_key())][i].get_key());
break;
}
}
A[hashkey(e.get_key())].push_back(e);
}
}
string Table::get(unsigned int key) const {
if( A[hashkey(key)].size() == 0) {
return "";
}
else {
for (size_t i = 0; i < A[hashkey(key)].size(); i++) {
if (A[hashkey(key)][i].get_key() == key) {
return A[hashkey(key)][i].get_data();
}
else {
return "";
}
}
}
}
bool Table::remove(unsigned int key) {
for (size_t i = 0; i < A[hashkey(key)].size(); i++) {
if (A[hashkey(key)][i].get_key() == key) {
swap(A[hashkey(key)][i],A[hashkey(key)][A[hashkey(key)].size() - 1]);
A[hashkey(key)].pop_back();
num_entries--;
return true;
}
else {
return false;
}
}
}
int Table::find(Entry e) {
for (size_t i = 0; i < A[hashkey(e.get_key())].size(); i++) {
if (A[hashkey(e.get_key())][i] == e) {
return i;
}
else {
return 0;
}
}
}
ostream& operator << (ostream& out, const Table& t) {
vector<Entry> order;
for(size_t i = 0; i < t.A.size(); i++) {
for (size_t j = 0; j < t.A[i].size(); j++) {
order.push_back(t.A[i][j]);
}
}
sort(order.begin(), order.end());
for(Entry k: order) {
out << k << endl;
}
return out;
}
unsigned int Table::hashkey(unsigned int key) const{
const double c = 1.61803;
// return key % size;
return (int)(size*((key * c) - (int)(key * c)));
}

C++ Int doesn't seem to be initializing and Exception thrown: read access violation

I'm very new to C++ so please excuse the sloppy code.
Here is the code in question:
Bag Class
class Bag {
protected:
Item* _myItems;
int _numItems;
int _size;
public:
Bag();
Bag(int size);
~Bag();
Bag(Bag& original);
void add(Item a);
void remove(int itemnum);
int size();
int numItems();
void operator=(Bag& bag);
Item& operator[] (int i);
};
//Empty constructor
Bag::Bag() {
_numItems = 0;
}
//overloaded constructor
Bag::Bag(int size) {
_numItems = 0;
_myItems = new Item[size];
}
//copy constructor
Bag::Bag(Bag& original) {
//Copies the numItems
_numItems = original._numItems;
//Makes a new copy of the original array
_myItems = new Item[_numItems];
//Copies each element of the original into the new
for (int i = 0; i < _numItems; ++i) {
_myItems[i] = original[i];
}
}
//Destructor
Bag::~Bag(){
delete[] _myItems;
}
//Returns the size of the bag
int Bag::size()
{
return _size;
}
//Returns the number of items in the bag
int Bag::numItems() {
return _numItems;
}
//Add a new item to the bag
void Bag::add(Item a) {
int s = _numItems;
//Create a Item pointer and assign it to the array of the bag
Item* temp = _myItems;
//Assign _myItems to a new, larger array
_myItems = new Item[_numItems++];
//Copy the old array into the new one and nullify all the old array's items
for (int i = 0; i < _numItems - 1; i++) {
_myItems[i] = temp[i];
}
//Destroy the old array
delete[] temp;
//Add the item to the last position
_myItems[_numItems] = a;
}
I am reading a text file line by line. The reading seems to be happening just fine. When I read in I execute this part of the code:
//The main program
int main() {
Pens * onePen = new Pens(1, 2);
Pens * twoPen = new Pens(2, 3);
Bag* bag = new Bag(5);
(*bag).add(onePen);
(*bag).add(twoPen);
bag[0];
bag[1];
int d = 0;
return 0;
}
I keep getting the Read Access Violation (This was 0xc) when I get into the add method. I also notice that when I put in breakpoints to examine the code, _numItems is not 0 but 211. Am I corrupting my memory somehow?
Here is a sample text file that we are using
Simplified version of the Bag and Pen classes (courtesy of PaulMcKenzie):
class Item {
protected:
int code_;
//Sets the method definition for the get/set methods and constructors
public:
Item(int code = -1);
virtual ~Item() {}
int getcode() const;
void setcode(int code);
std::ostream& operator<< (std::ostream& s);
bool operator== (const Item& a) const;
};
Item::Item(int code) : code_(code) {}
int Item::getcode() const { return code_; }
void Item::setcode(int code) { code_ = code; }
std::ostream & Item::operator<<(std::ostream& s)
{
s << " Code - " << code_ << "\n";
return s;
}
bool Item::operator==(const Item & a) const
{
return (code_ == a.getcode());
}
class Pens : public Item
{
private: int packetsize_;
public:
Pens();
Pens(int code, int packetsize);
int getpacketsize() const;
void setpacketsize(int packetsize);
bool operator== (const Pens& a) const;
};
Pens::Pens() :Item() { }
Pens::Pens(int code, int packetsize) : Item(code), packetsize_(packetsize) {}
int Pens::getpacketsize() const { return packetsize_; }
void Pens::setpacketsize(int packetsize) { packetsize_ = packetsize; }
std::ostream& operator<<(std::ostream& s, const Pens& pen)
{
s << " Packet size: " << pen.getpacketsize() << "\n";
return s;
}
bool Pens::operator==(const Pens & a) const
{
return code_ == a.getcode() && packetsize_ == a.getpacketsize();
}
I did not look in depth but this segment caught my eye:
//Add a new item to the bag
void Bag::add(Item a) {
int s = _numItems;
//Create a Item pointer and assign it to the array of the bag
Item* temp = _myItems;
//Assign _myItems to a new, larger array
_myItems = new Item[_numItems++];
//Copy the old array into the new one and nullify all the old array's items
for (int i = 0; i < _numItems - 1; i++) {
_myItems[i] = temp[i];
}
//Destroy the old array
delete[] temp;
//Add the item to the last position
_myItems[_numItems] = a;
}
Please look at this line:
_myItems = new Item[_numItems++];
You create new array with size of _numItems and then increase the _numItems by 1.
Which in my humble opinion leaves you with array of size _numItems-1.
And then you try to use element _myItems[_numItems] so this may be the reason of memory corruption.

Building a 2D array class from a 1D array class in C++

in my C++ class we are finally getting conceptually fairly deep (well, relatively!) and I'm struggling with building a class from a previous class.
Here is my first class header, which builds partially filled array objects. To my knowledge, it is fully functional:
#ifndef PARTIALARRAY_H
#define PARTIALARRAY_H
#include <iostream>
#include <string.h>
using namespace std;
typedef int ITEM_TYPE;
ITEM_TYPE const MAX = 50;
class PartialArray
{
public:
//-----------------------------------------ctors:-----------------------------------------
PartialArray();
PartialArray(const int init[], int used);
//-----------------------------------------member functions:-----------------------------------------
void PrintArray();
int Search(ITEM_TYPE key);
int Append(ITEM_TYPE appendMe);
int ShiftRight(int shiftHere);
int ShiftLeft(int shiftHere);
int InsertBefore(ITEM_TYPE insertThis, int insertHere);
int InsertAfter(ITEM_TYPE insertThis, int insertHere);
int Delete(int deleteHere);
void DeleteRepeats();
int NumUsed();
void Sort();
void Reverse();
string ErrorDescr(int failCode);
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& operator [] (ITEM_TYPE x);
private:
//-----------------------------------------member vars:-----------------------------------------
ITEM_TYPE a[MAX];
int numUsed;
};
#endif // PARTIALARRAY_H
And here are the class functions:
#include "partialarray.h"
#include <iostream>
#include <string.h>
using namespace std;
//-----------------------------------------ctors:-----------------------------------------
PartialArray::PartialArray()
{
numUsed=0;
}
PartialArray::PartialArray(const int init[], int used)
{
numUsed = used;
for(int i=0; i<numUsed; i++)
{
a[i]=init[i];
}
}
//-----------------------------------------member functions:-----------------------------------------
//Prints the array up to its last used element
void PartialArray::PrintArray()
{
for(int i=0; i<numUsed; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
//Searches the array for a particular value and returns the index at which the value first appears
int PartialArray::Search(ITEM_TYPE key)
{
for(int i=0; i<numUsed; i++)
{
if(a[i]==key)
return i;
}
return -1;
}
//Takes a number and appends it to the end of the array after the last interesting element
int PartialArray::Append(ITEM_TYPE appendMe)
{
if(numUsed<MAX)
a[numUsed++] = appendMe;
else
return 1;
return 0;
}
//Shifts all elements of the array to the right starting at a particular index
int PartialArray::ShiftRight(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[numUsed-1];
for(int i=numUsed; i>=shiftHere; i--)
{
a[i] = a[i-1];
}
a[shiftHere] = save;
return 0;
}
else
return 2;
}
//Shifts all elements of the array to the left starting at a particular index
int PartialArray::ShiftLeft(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[shiftHere];
for(int i=shiftHere; i<numUsed; i++)
{
a[i] = a[i+1];
}
a[numUsed-1] = save;
return 0;
}
else
return 2;
}
//Takes a number and a position and inserts the number before that position in the array shifting the elements to the right
int PartialArray::InsertBefore(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else
{
numUsed++;
ShiftRight(insertHere);
a[insertHere] = insertThis;
}
return 0;
}
//Takes a number and a position and inserts the number after that position in the array shifting the elements to the right
int PartialArray::InsertAfter(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else if(numUsed>=MAX)
return 1;
else
{
numUsed++;
ShiftRight(insertHere+1);
a[insertHere+1] = insertThis;
}
return 0;
}
//Takes a position and removes that item from the array, shifting all the elements to the left
int PartialArray::Delete(int deleteHere)
{
if(deleteHere <= numUsed)
{
ShiftLeft(deleteHere);
numUsed--;
return 0;
}
else
return 2;
}
//Deletes repeated elements in the array and replaces the with 0
void PartialArray::DeleteRepeats()
{
for(int i=0;i<numUsed;i++)
{
ITEM_TYPE n=a[i];
for(int j=i+1; j<numUsed;j++)
{
if(n == a[j])
{
Delete(j);
j--;
}
}
}
}
//Returns number of interesting elements in the array
int PartialArray::NumUsed()
{
return numUsed;
}
//Utilizes a bubble sort algorithm
void PartialArray::Sort()
{
bool swap = true;
int j = 0;
int save;
while (swap==true)
{
swap = false;
j++;
for (int i = 0; i < numUsed - j; i++)
{
if (a[i] > a[i + 1])
{
save = a[i];
a[i] = a[i + 1];
a[i + 1] = save;
swap = true;
}
}
}
}
void PartialArray::Reverse()
{
for(int i=0;i<numUsed-1;i++)
{
ITEM_TYPE save = a[numUsed-1];
ShiftRight(i);
a[i] = save;
}
}
//Returns the appropriate error description for a particular fail code
string PartialArray::ErrorDescr(int failCode)
{
switch(failCode)
{
case -1:
return "ERROR: item not found";
break;
case 1:
return "ERROR: array is full";
break;
case 2:
return "ERROR: unused index";
break;
default:
return "UNKNOWN ERROR";
break;
}
}
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& PartialArray::operator [](ITEM_TYPE x)
{
return a[x];
}
Now, here is where things have gotten tricky. To build the two dimensional array class, I'm supposed to create an array of arrays. I'm at a loss as to how I should go about this, and after tinkering and googling for a few hours I've only become more confused. Specifically, the <<, [], and [](constant version) operators and the TwoDArray constructor have thrown me for a loop, and I'm stuck without much sense of what to do next. Here is the TwoD header file:
#ifndef TWODARRAY_H
#define TWODARRAY_H
#include "partialarray.h"
#include <iostream>
#include <string.h>
typedef int ITEM_TYPE;
class TwoDArray
{
friend ostream& operator << (ostream &outs, const TwoDArray& printMe);
public:
//ctors:
TwoDArray();
//member functions:
//PartialArray& operator [](int index); //[ ] operator for the TwoDArray object
//PartialArray operator [](int index) const; //[ ] operator for the TwoDArray object (const version)
int Append(int appendMe, int row);
int InsertBefore(int insertMe, int row, int column);
int InsertAfter(int insertMe, int row, int column);
int Delete(int row, int column);
bool Search(ITEM_TYPE key, int &row, int &column);
private:
//member vars:
PartialArray a[MAX];
};
#endif // TWODARRAY_H
And this is what I've tried to define thus far:
TwoDArray::TwoDArray()
{
const int array0[]= {0};
PartialArray array(array0, MAX);
}
ostream& operator << (ostream &outs, const TwoDArray& printMe)
{
for(int i=0;i<MAX;i++)
{
outs << printMe.a[i];
}
return outs;
}
Ideally, the << operator will print an m by n array of items.

Stack of strings. Deleting an even element

everyone!
I'm trying to do such task:
Create stack od strings, by writing several constructors, including copy constructor. All elements are hleds in an array. If an array have fixed size, in case of overloading, increase it. Create pop(), push() functions. Make a function, deleting every even element.
Got problem, after sizing of the stack
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstddef>
using namespace std;
class Stack
{
string *stck; //stack pointer
int sz; //stack size
int ts; //top of the stack
public:
//constructor
Stack(int size)
{
size=sz;
stck = new string[sz];
ts = -1;
};
//destructor
~Stack() {
delete []stck;
};
//copy constructor
Stack (const Stack &ob);
void Push(string itm);
string Pop();
void Show(int sz);
private:
void Resize(int sz);
};
void Stack::Push(string itm)
{
if (ts == sz)
{
cout<<"Stack is overflow"<<endl;
Resize(ts);
}
else stck[ts++] = itm;
}
string Stack::Pop()
{
if(ts<0)
{
cout<<"Stack is free"<<endl;
return 0;
}
else return stck[--ts];
}
void Stack::Show(int sz)
{
for (int i = 0; i < sz; i++)
{
std::cout << stck[i] << std::endl;
}
}
Stack::Stack (const Stack &ob)
{
cout<<"Copy constructor allocating stackPtr)"<<endl;
stck = new string;
*stck = *ob.stck;
}
//функция выделения дополнительной памяти
void Stack::Resize(int idx)
{
int new_size = sz;
while (new_size < idx)
new_size *=2;
string *new_arr = new string[new_size];
for(int i = 0; i < sz; i++)
new_arr[i] = stck[i];
delete[] stck;
stck = new_arr;
sz = new_size;
}
int main()
{
cout<<"Enter the size of the stack"<<endl;
int n;
cin>>n;
Stack mystck(n);
string str;
for(int i=0; i<n; i++)
{
cout<<"Enter an element"<<endl;
cin>>str;
mystck.Push(str);
}
for(int j = 0; j<n; j+2)
{
mystck.Pop();
mystck.Show(n);
}
return 0;
}
Can anybody help me with fixing that case?