C++ change from struct to classes [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I am looking to change this from struct to classes and use a header file to hold the class.
What would you suggest in way of changing it over. The code all works. There is no problem there. just a simple change over question.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
struct printype
{
char dots[8][15];
int unknown15; // can have values of 0..127
string serial11_14; // 8 characters 00000000...99999999
int year8; // without century, 0..99
int month7; // 1..12
int day6; // 1..31
int hour5; // 0..23
int minute2; // 0..59
};
int getunknown15(); // prototypes
string getserial11_14();
int getyear8();
int getmonth7();
int getday6();
int gethour5();
int getminute2();
int setunknown15(int); //------------------------- protos
string setserial11_14(string);
int setyear8(int);
int setmonth7(int);
int setday6(int);
int sethour5(int);
int setminute2(int);
// int array and display info for array
void setup(char[8][15]);
// display array
void darray(char[8][15]);
// displays printer information
void dpinfo(printype);
// set parrity
void spar(char[8][15]);
// fill array
void ftarray(printype &); //----------------------end protos
//-------------------------------------
void main ()
{
printype pt;
pt.unknown15=getunknown15();
pt.unknown15=setunknown15(pt.unknown15);
pt.serial11_14=getserial11_14();
pt.serial11_14=setserial11_14(pt.serial11_14);
pt.year8=getyear8();
pt.year8=setyear8(pt.year8);
pt.month7=getmonth7();
pt.month7=setmonth7(pt.month7);
pt.day6=getday6();
pt.day6=setday6(pt.day6);
pt.hour5=gethour5();
pt.hour5=sethour5(pt.hour5);
pt.minute2=getminute2();
pt.minute2=setminute2(pt.minute2);
cout <<"-----------------------------------------------------"<<endl;
cout <<" Lets Get Started"<<endl;
cout <<"-----------------------------------------------------"<<endl;
setup(pt.dots); // sets up the array
dpinfo(pt); // prints out the final array
ftarray(pt);
spar(pt.dots);
darray(pt.dots);
}
int getunknown15()
{
printype tem;
cout <<"-----------------------------------------------------"<<endl;
cout <<" Enter the Unkown Variable (0-127): ";
cin >>tem.unknown15;
cout <<"-----------------------------------------------------"<<endl;
return tem.unknown15;
}
string getserial11_14()//------------------------------------------ starts the get information sets
{
printype tem;
cout <<" Enter the Serial Variable (8char long): ";
cin >>tem.serial11_14;
cout <<"-----------------------------------------------------"<<endl;
return tem.serial11_14;
}
int getyear8()
{
printype tem;
cout <<" Enter the Year Variable (2char long): ";
cin >>tem.year8;
cout <<"-----------------------------------------------------"<<endl;
return tem.year8;
}
int getmonth7()
{
printype tem;
cout <<" Enter the Month Variable (2char long): ";
cin >>tem.month7;
cout <<"-----------------------------------------------------"<<endl;
return tem.month7;
}
int getday6()
{
printype tem;
cout <<" Enter the Day Variable (2char long): ";
cin >>tem.day6;
cout <<"-----------------------------------------------------"<<endl;
return tem.day6;
}
int gethour5()
{
printype tem;
cout <<" Enter the Hour Variable (2char long): ";
cin >>tem.hour5;
cout <<"-----------------------------------------------------"<<endl;
return tem.hour5;
}
int getminute2()
{
printype tem;
cout <<" Enter the Minute Variable (2char long): ";
cin >>tem.minute2;
cout <<"-----------------------------------------------------"<<endl;
return tem.minute2;
}
//-----------------------------------------------------------put functions (adds info to the array)
int setunknown15(int tem)
{
printype pp;
if (tem>127||tem<0)
{
cout << "Error" << endl;
return 0;
}
else
{
pp.unknown15 = tem;
return pp.unknown15;
}
}
string setserial11_14(string tem)
{
printype pp;
if(tem.size() !=8)
{
cout <<"nope.jpg"<<endl;
return 0;
}
else
{
for (int i = 0; i < 8; i++)
{
if(!isdigit(tem.at(i)))
{
cout<<"nope.jpg"<<endl;
return 0;
}
}
pp.serial11_14=tem;
return pp.serial11_14;
}
}
int setyear8(int tem)
{
printype pp;
if(tem>99||tem<0)
{
cout<<"nope.jpg"<<endl;
return 0;
}
else
{
pp.year8=tem;
return pp.year8;
}
}
int setmonth7(int tem)
{
printype pp;
if(tem>12||tem<1)
{
cout<<"nope.jpg"<<endl;
return 0;
}
else
{
pp.month7=tem;
return pp.month7;
}
}
int setday6(int tem)
{
printype pp;
if(tem>31||tem<1)
{
cout<<"nope.jpg"<<endl;
return 0;
}
else
{
pp.day6=tem;
return pp.day6;
}
}int sethour5(int tem)
{
printype pp;
if(tem>23||tem<0)
{
cout<<"nope.jpg"<<endl;
return 0;
}
else
{
pp.hour5=tem;
return pp.hour5;
}
}
int setminute2(int tem)
{
printype pp;
if(tem>59||tem<0)
{
cout<<"nope.jpg"<<endl;
return 0;
}
else
{
pp.minute2=tem;
return pp.minute2;
}
}
void setup(char tem[8][15])
{
for (int x=0;x<8;x++)// set to all blanks
{
for (int y=0;y<15;y++)
{
tem[x][y]=' ';
}
}
}
void darray(char tem[8][15])
{
for (int x=0;x<8;x++)// set to all blanks
{
cout <<"\t-------------------------------"<<endl;
cout <<"\t|";
for (int y=0;y<15;y++)
{
cout << tem[x][y];
cout<<"|";
}
cout <<"\n";
}
cout <<"\t-------------------------------"<<endl;
}
void dpinfo(printype mc)
{
cout <<"The unknown is:\t"<<mc.unknown15<<"\nThe String is:\t"<<mc.serial11_14<<"\n Time:\n\n Year: 20"<<mc.year8<<" month: "<<mc.month7<<"\n day: "<<mc.day6<<" hour: "<<mc.hour5<<"\n minute: "<<mc.minute2<<endl;
}
void spar(char tem[8][15])
{
int count=0;
for (int x=0;x<7;x++)
{
for (int y=0;y<15;y++)
{
if(tem[x][y]=='*')
{
count+=1;
}
}
if(count%2==0)
{
tem[x][0]='*';
}
}
count=0;
for (int a=0;a<7;a++)
{
for (int z=0;z<7;z++)
{
}
}
}
void ftarray(printype &pt)
{
int tem=0;
for (int x=1;x<15;x++)
{
switch(x)
{
case 1:
{
tem=pt.minute2;
break;
}
case 4:
{
tem=pt.hour5;
break;
}
case 5:
{
tem=pt.day6;
break;
}
case 6:
{
tem=pt.month7;
break;
}
case 7:
{
tem=pt.year8;
break;
}
case 9:
{
for (int j = 1; j < 8; j++)
{
pt.dots[j][x] = '*';
}
}
case 10:
{
tem=atoi(pt.serial11_14.substr(6,2).c_str());
break;
}
case 11:
{
tem=atoi(pt.serial11_14.substr(4,2).c_str());
break;
}
case 12:
{
tem=atoi(pt.serial11_14.substr(2,2).c_str());
break;
}
case 13:
{
tem=atoi(pt.serial11_14.substr(0,2).c_str());
break;
}
case 14:
{
tem=pt.unknown15;
break;
}
}
if(x==1||x==4||x==5||x==6||x==7||x==10||x==11||x==12||x==13||x==14)
{
if (tem>=64)
{
pt.dots[1][x]='*';
tem-=64;
}
if (tem>=32)
{
pt.dots[2][x]='*';
tem-=32;
}
if (tem>=16)
{
pt.dots[3][x]='*';
tem-=16;
}
if (tem>=8)
{
pt.dots[4][x]='*';
tem-=8;
}
if (tem>=4)
{
pt.dots[5][x]='*';
tem-=4;
}
if (tem>=2)
{
pt.dots[6][x]='*';
tem-=2;
}
if (tem>=1)
{
pt.dots[7][x]='*';
tem-=1;
}
}
}
}

In C++, struct and class is the same thing, other than the default access level. All you need to do is replace
struct printype
{
//...
};
with
class printype
{
public:
//...
};
You can also probably replace the functions that take a printype as argument by value with member functions:
void dpinfo(printype);
becomes
class printype
{
public:
//....
void dpinfo();
};
and will operate on this rather than the parameter.
Methods that return an object printype can become constructors.
I suspect however you have several issues with your code:
int getunknown15()
{
printype tem;
cout <<"-----------------------------------------------------"<<endl;
cout <<" Enter the Unkown Variable (0-127): ";
cin >>tem.unknown15;
cout <<"-----------------------------------------------------"<<endl;
return tem.unknown15;
}
Here, for example, you don't need the tem variable... it does nothing. You can directly read an int an return that, tem will be destroyed on function exit anyway.
Maybe you're looking for a member function, for example:
int printype::setyear8(int tem)
{
if(tem>99||tem<0)
{
cout<<"nope.jpg"<<endl;
return 0;
}
else
{
this->year8=tem;
return this->year8;
}
}
This way the object is modified and you don't lose changes. However, your coding style suggests little to no knowledge of oop. I suggest reading a good book before continuing, as I doubt that, as it is, the answer will make much sense to you.

First of all, a struct and a class are the same in C++, only difference is that a struct is default public and a class is default private. All you do is change struct to class
Looking at your code, however, I'm assuming you are converting from C to C++ and want to add your functions as methods to the class. To do this, you simply add the prototypes to the class declaration and then add the class space to the function implementations. You should also add any relevant constructors and a destructor in necessary
In a h file
class Printype {
char **dots;
int unknown15; // can have values of 0..127
string serial11_14; // 8 characters 00000000...99999999
int year8; // without century, 0..99
int month7; // 1..12
int day6; // 1..31
int hour5; // 0..23
int minute2; // 0..59
//Constructors
Printype(); //Default
Printype(const Printype &cpy); //Copy
Printype(int yr, int mo, int d, int hr, int min); //Sample initializer
//Destrutor
~Printype();
//Methods (only gonna do 2 for example)
int getYear();
void setYear(int y);
};
In a cpp or cc file
#include "printype.h"
Printype::Printype() {
dots = new char*[8];
for(int i=0;i<8;++i) {
dots[i] = new char[15];
}
unknown15 = 0; serial11_14 = ""; year8 = 0;
month7 = 0; day6 = 0; hour5 = 0;minute2 = 0;
}
Printype::Printype(const Printype &cpy) {
//Deep copy all values from cpy to this
}
Printype::Printype() {
dots = new char*[8];
for(int i=0;i<8;++i) {
dots[i] = new char[15];
}
unknown15 = 0; serial11_14 = ""; year8 = yr;
month7 = mo; day6 = d; hour5 = hr;minute2 = min;
}
//Destructor (free allocated memory)
Printype::~Printype() {
for(int i=0;i<8;++i) {
delete[] dots[i]; dots[i] = NULL;
}
delete[] dots; dots = NULL;
}
//Methods
int Printype::getYear() {
return year8;
}
void Printype::setYear(int y) {
year8 = y;
}
You should also implement an = operator. Hope this gets you started and answers your question though. You should really read up on some general OOP in addition to C++ syntax, patterns, etc. A lot of this will likely look foreign and not make much sense, and it will take to long to explain in this forum. There are tons of resources online regarding this material so you should try to read up on it.

Related

How do you sort a string within a class parameter?

My professor has asked us to make a program that will take a user's input and continue reading until the end of input. Only then, can the program output what the user has typed.
Input should be based on video title, it's url, comments made on the video, length (in minutes), and rating (in *).
For example:
United Break Guitars, https://www.youtube.com/watch?v+5YGc4zOqozo, Great example of one person getting a giant company to listen, 4.5, ***, Space Versus Tabs, https://www.youtube.com/watch?v=SsoOG6ZeyUl, Decide for yourself: spaces or tabs?, 2.83, ****
Before inputting any video description, the user needs to specify a sorting method of three choices, Rating, Length, or title. I have completed most of the code and sort method asked by my professor (bubble sort), however when I ask the program to sort by title (which is the only one of the three options that is a string), it does not output correctly.
Here is my code:
#include <iostream>
#include <stdlib.h>
#include <cstring>
using namespace std;
#include "video.h"
int main()
{
string user, url, comment, title;
int rating;
double length;
int i = 0, last = 0;
Video *videoObj[100];
// specifies how the videos should be sorted
cin >> user;
cin.ignore();
while (getline(cin,title) ) {
getline(cin, url);
getline(cin, comment);
cin >> length;
cin >> rating;
cin.ignore();
videoObj[i] = new Video(title, url, comment, length, rating);
i++;
last++;
}
//------------------------------------------------------------------------
//--------------- Sorts the list based on rating (*) ---------------------
//------------------------------------------------------------------------
if(user=="rating"){
for(int i = 0; i < last - 1; i++){
for(int j = 0; j< last - i -1; j++){
if(videoObj[j +1]->Rating(videoObj[j])){
swap(videoObj[j], videoObj[j+1]);
}
}
}
}
//------------------------------------------------------------------------
//--------------- Sorts the list based on length -------------------------
//------------------------------------------------------------------------
if(user=="length"){
for(int i = 0; i < last - 1; i++){
for(int j = 0; j< last - i -1; j++){
if(videoObj[j +1]->Length(videoObj[j])){
swap(videoObj[j], videoObj[j+1]);
}
}
}
}
//------------------------------------------------------------------------
//--------------- Sorts the list based on title --------------------------
//------------------------------------------------------------------------
if(user=="title"){
for(int i = 0; i < last - 1; i++){
for(int j = 0; j< last - i -1; j++){
if(videoObj[j +1]->Title(videoObj[j])){
swap(videoObj[j], videoObj[j+1]);
}
}
}
}
for(int i= 0; i < last; i++){
videoObj[i]->print();
}
//delete[] videoObj;
return 0;
}
video.cpp:
#include <iostream>
#include <algorithm>
using namespace std;
#include "video.h"
Video::Video(string video_title, string video_link, string video_comment, double video_length, int video_number)
: title(video_title), link(video_link), comment(video_comment), length(video_length), rating(video_number)
{
m_title = title;
m_link = link;
m_comment = comment;
m_length = length;
m_rating = rating;
}
bool Video::Rating(Video *other)
{
if(m_rating > other-> m_rating){
return true;
}
else
{
return false;
}
}
bool Video::Length(Video *other2)
{
if(m_length > other2-> m_length){
return true;
}
else
{
return false;
}
}
bool Video::Title(Video *other3)
{
if(m_length > other3-> m_length){
return true;
}
else
{
return false;
}
}
void Video::print(){
string star;
switch(rating){
case 1:
star = "*";
break;
case 2:
star = "**";
break;
case 3:
star = "***";
break;
case 4:
star = "****";
break;
case 5:
star = "*****";
break;
}
cout << title << ", " << link << ", " << comment << ", " << length << ", " << star << endl;
}
video.h:
#ifndef VIDEO_H
#define VIDEO_H
using namespace std;
class Video {
public:
Video(string video_title, string video_link, string video_comment, double video_length, int video_number);
void print();
bool Rating(Video *other);
bool Length(Video *other2);
bool Title(Video *other3);
private:
string m_title;
string m_link;
string m_comment;
double m_length;
int m_rating;
string title;
string link;
string comment;
double length;
int rating;
};
#endif
I'm not exactly sure what I need to do to title to make it function correctly. I was thinking of comparing by strings, but again, not sure where to start.
Also, another question, how do I use delete[] videoObj;without getting an error?
Well this is wrong, just a typo probably
bool Video::Title(Video *other3)
{
if(m_length > other3-> m_length){
return true;
}
else
{
return false;
}
}
It should be m_title not m_length (probably)
bool Video::Title(Video *other3)
{
if(m_title > other3-> m_title){
return true;
}
else
{
return false;
}
}
Also this code can be simplified, the above can be written in one line
bool Video::Title(Video *other3)
{
return m_title > other3-> m_title;
}
if (xxx) return true; else return false; is exactly the same as return xxx;. Beginners often don't realise you can calculate with booleans in this is way.

Getter and Segmentation Fault

I need a bit of help on my program:
#include <iostream>
#include<conio.h>
using namespace std;
class Position {
public :
int line;
int column;
Position(int,int);
Position();
};
Position::Position(int n, int m) : line{n},column{m}{}
class Board {
private :
int** tab;
int nbline;
int nbcolumn;
public :
Board(int, int);
void setValue(Position&, int);
int getValue(Position&);
int getNbline();
int getNbcolumn();
};
class Play {
private :
// Play m_instance;
void moves(Board, Position&); // quand le joueur joue
// void moves(Board, Position); // quand l'IA joue. Mettre une énum pour direction,
bool wincondition(Board);
Play& operator=(const Play&);
public :
// static Play& Instance();
};
Board::Board(int m, int n) : tab{new int*[m]}, nbline{m}, nbcolumn{n}{
int x(0);
for (int i = 0; i < m; ++i){
tab[i] = new int[n];
for(int j = 0; j < n; ++j) {
tab[i][j] = x; x++;}}
}
void Board::setValue(Position& p, int value) { tab[p.line][p.column] = value; }
int Board::getValue(Position& p) { return tab[p.line][p.column]; }
int Board::getNbline() { return nbline; }
int Board::getNbcolumn() { return nbcolumn; }
void Play::moves(Board tab, Position& blank) {
/* int c = getch() ;
Position tmp;
if(c==0 || c==224) {c = getch();
switch(c){
case 75 : //left
if(blank.column-1>=0) {
tmp.column = blank.column;
tmp.line = blank.line;
tab.setValue(blank,tab.getValue(tmp));
blank.column++;
tab.setValue(blank, 0);
}
break;
case 72 : // haut
if(blank.line+1<=0) {
tmp.column = blank.column+1;
tmp.line = blank.line;
tab.setValue(blank,tab.getValue(tmp));
blank.column++;
tab.setValue(blank, 0);
}
break;
case 77 ://droit
if(blank.column+1<=tab.getNbcolumn()) {
tmp.column = blank.column;
tmp.line = blank.line;
tab.setValue(blank,tab.getValue(tmp));
blank.column--;
tab.setValue(blank, 0);
}
break;
case 80 : //bas
if(blank.line+1<=tab.getNbline()) {
tmp.column = blank.column+1;
tmp.line = blank.line;
tab.setValue(blank,tab.getValue(tmp));
blank.column++;
tab.setValue(blank, 0);
}
break;
default : cout << "\n ERROR " << endl; break; // erreur
}
}*/
}
int main()
{
int lines, columns;
cout << "Enter number of lines" << endl;
cin >> lines;
cout << "Enter number of columns" << endl;
cin >> columns;
Board tab(lines,columns);
Position pos(lines,columns);
Position& p = pos;
for (int i = 0; i<lines;i++)
{
for(int j = 0; j<columns;j++)
{
cout << tab.getValue(p) << " ";
if (i == lines) { cout << endl;}
}
}
return 0;
}
When I call getValue at line 139, I get a segmentation fault. Get value is defined at line 57. When executing getValue, both p.line and p.column got the right values caught at the beginning of main function.
The program got no errors, only 2 warnings because I don't use Play::moves arguments (because currently between /* */, waiting for tests). I use Code::Blocks with -Wall -Wextra -pedantic -std=c++11.
I really see no reason for a segmentation fault. Did I miss something?
You are calling get with a position that is set to the size of your board. Since arrays are 0 index based the size of your array is actually one past the end of the array.
const int size = 100
int arr[size]; //0, 1, 2, ... 98, 99
arr[size]; // fail arr is 0-99 and size is 100

C++ GET Array Error

I am having a problem with pieces[] at Copy Constructor and Equal Oparator. i am trying to get pieces like code and month_year but it drops me an error saying 'class machine' has no member named 'get'
#include <iostream>
#include <string>
using namespace std;
class machine {
public:
void set_code(string my_code){
code=my_code;
}
void set_month_year(int my_month_year){
month_year=my_month_year;
}
void set_pieces(int *my_pieces){
for(int i=0;i<25;i++)
pieces[i]=my_pieces[i];
}
string get_code(void){
return code;
}
int get_month_year(void){
return month_year;
int get_pieces_i(int i){
return pieces[i];
}
//Default Constructor
machine(){
code.erase();
month_year=0;
for(int i=0;i<25;i++)
pieces[i]=0;
}
//Destructor
~machine(){}
void print_data(void){
cout << "Code= " << code << endl;
cout << "Month Year " << month_year << endl;
}
void print_pieces(void){
for(int i=0;i<25;i++)
cout << pieces[i] << endl;
}
machine(string my_code, int my_month_year,int *my_pieces){
code=my_code;
month_year=my_month_year;
for(int i=0;i<25;i++)
pieces[i]=my_pieces[i];
}
//Copy Constructor
machine (machine& a)
{
code=a.get_code();
month_year=a.get_month_year();
pieces=a.get.pieces_i();
}
//Equal Operator
void operator = (machine & a)
{
code=a.get_code();
month_year=a.get_month_year();
pieces=a.get_pieces_i();
}
// month & year
int get_month(void) {
return month_year/100;
}
int get_year(void) {
return month_year%100;
}
//return 0 & 1
int ckeck_code(void) {
int counter=0;
for (int i=0;i<25;i++) {
if (pieces [i] <10) {
counter=counter+1;
}
if (counter<5)
return 0;
else
return 1;
}
}
private:
string code;
int month_year;
int pieces[25];
};
int main(void){
return 0;
}
Both copy constructor and assignment operator (yes, it's called assignment operator, not equal operator) should have their parameter of type const machine& instead of machine&.
On the get_* functions, they should be declared as constant member functions. That is,
string get_code(void) const {
return code;
}
int get_month_year(void) const {
return month_year;
}
int get_pieces_i(int i) const {
return pieces[i];
}
Furthermore, the copy constructor and assignment operator should handle pieces like:
for (int i = 0; i < 25; ++i)
pieces[i] = a.get_pieces_i(i);
to match the getters' prototype.

array of strings inside the object

I've got a problem with creating an array of strings inside the object. I don't know how to patch it around so I'm asking for help. Here lies the problem:
main.h:
#pragma once
#include <iostream>
#include <conio.h>
#include <string>
class tab2D {
protected:
int width;
int height;
string **sTab;
int **iTab;
public:
tab2D();
tab2D(int x, int y, char c);
~tab2D();
tab2D(tab2D&t);
};
class chess: public tab2D {
public:
chess(int x, int y);
~chess();
chess(chess&c);
void init();
bool ifMove();
void show();
};
class matrix: public tab2D {
public:
matrix(int x, int y);
~matrix();
matrix(matrix&m);
};
The compiler says: syntax error : missing ';' before '*' about the line
string **sTab;
I assume that I can't make the dynamic array of strings and it makes further problems with processing this array.. Can you help me? :)
*UPDATE 1*Thanks, I forgot to add line
using namespace std;
Now it works, but I've got another problem.
#include "main.h"
using namespace std;
////// Konstruktor, konstruktor kopiujący oraz destruktor //////
chess::chess(int x = 8, int y = 8) : tab2D(x, y, 'c') {
init();
};
chess::chess(chess&c) {
chess(c.width, c.height);
};
chess::~chess() {
};
////// Metody //////
////// Uzupełnianie kolorów pól oraz rozstawianie figur i pionków //////
void chess::init() {
/// kolory pól: 0 - biały, 1 - czarny///
int last = 0;
for(int i = 0; i < this->height; ++i) {
for(int j=0; j < this->width; ++j) {
if(last = 0) {
this->sTab[i][j] = "1";
last = 1;
}
else if(last = 1) {
this->sTab[i][j] = "0";
last = 0;
}
}
if(last = 0)
last = 1;
else if(last = 1)
last = 0;
};
/// rozstawienie pionków ///
for(int i = 0; i < this->width; ++i) {
sTab[1][i] = sTab[1][i] + "0";
sTab[6][i] = sTab[6][i] + "a";
};
};
////// Wyświetlenie szachownicy //////
void chess::show() {
for(int i = 0; i < (this->height + 1); ++i) {
for(int j=0; j < (this->width + 1); ++j) {
if(i == 0 && j == 0)
cout << " ";
else if (i != 0 && j == 0) {
switch (i) {
case 1:
cout << "A ";
break;
case 2:
cout << "B ";
break;
case 3:
cout << "C ";
break;
case 4:
cout << "D ";
break;
case 5:
cout << "E ";
break;
case 6:
cout << "F ";
break;
case 7:
cout << "G ";
break;
case 8:
cout << "H ";
break;
default:
break;
}
}
else if (i == 0 && j != 0) {
cout << j << " ";
}
else {
cout << this->sTab[i-1][j-1] << " ";
}
}
cout << endl;
};
};
When I run the program, there is a breakpoint in the line
this->sTab[i][j] = "0";
I assume there is something wrong with making the array of strings but I don't understand why exactly there is a breakpoint and can't debug it.
UPDATE 2
Here is the code for tab.cpp:
#include "main.h"
using namespace std;
////// Konstruktor domyślny, konstruktor, konstruktor kopiujący oraz destruktor //////
tab2D::tab2D() {
};
tab2D::tab2D(int x, int y, char c) {
this->width = x;
this->height = y;
if (c == 'm') {
this->iTab = new int*[this->width];
for(int i=0;i<this->height;++i)
this->iTab[i] = new int[this->width];
}
else if (c == 'c') {
this->sTab = new string*[this->width];
for(int i=0;i<this->height;++i)
this->sTab[i] = new string[this->width];
}
else {
}
};
tab2D::tab2D(tab2D&t) {
tab2D(t.width, t.height, 't');
};
tab2D::~tab2D() {
for(int i=0;i<height;++i)
delete [] iTab[i];
delete [] iTab;
for(int i=0;i<height;++i)
delete [] sTab[i];
delete [] sTab;
};
You need to qualify names from the standard library:
std::string **sTab;
^^^^^
If you're doing what I think you're doing and allocating things with new, then you should consider using std::vector to deal with the quagmire of memory management issues you're about to encounter. If you really want to juggle pointers yourself for some reason, don't forget the Rule of Three.
UPDATE Your new problem might be because the copy constructor is horribly broken:
chess::chess(chess&c) {
chess(c.width, c.height);
};
This creates and destroys a temporary object, but doesn't initialise the object being constructed, leaving it in an invalid state. You probably don't want to declare a copy-constructor at all, as long as the base class is correctly copyable. If you did need one, it should should be more like:
chess::chess(chess const & c) : // 'const' so constant objects can be copied
tab2D(c) // copy the base-class subobject
{
// do whatever else needs doing
}
Alternatively, the new problem might be due to errors in the tab2D constuctors which you haven't shown us. The best way to track it down is to step through the program with a debugger, checking that everything is correctly initialised before use.
UPDATE Probably, the runtime error is caused by allocating the wrong number of pointers. You want
iTab = new int*[height]; // Not width
and likewise for sTab.

Why doesn't the second class name get filled when I tell it to?

When I call the function to fill the second class, it just passes it somehow. It is not the call function (fill()) that has an error because I wrote that after I was having this problem. The code is posted below:
class Name_pairs {
public:
void read_names();
void read_ages();
void sort();
vector<string> names() const { return name; }
vector<double> ages() const { return age; }
private:
vector<string> name;
vector<double> age;
};
void Name_pairs::read_names() {
string s;
while(cin>>s) {
if(s == "|")
break;
name.push_back(s);
}
}
void Name_pairs::read_ages() {
double d;
while(cin>>d) {
if(d < 0)
break;
age.push_back(d);
}
}
void Name_pairs::sort() {
vector<string> dup_name = name;
vector<double> dup_age = age;
std::sort(name.begin(), name.end());
double buffer;
for(int i = 0; i < name.size(); i++) {
for(int ii = 0; ii < dup_name.size(); ii++) {
if(name[i] == dup_name[ii]) {
buffer = age[i];
age[i] = dup_age[ii];
break;
}
}
}
return;
}
void fill(Name_pairs& np)
{
np.read_names();
np.read_ages();
np.sort();
}
int main() try
{
Name_pairs test;
Name_pairs test1;
fill(test);
fill(test1);
return 0;
}
It looks like your Name_pairs::read_ages() method reads from cin until the stream is closed. When you call fill the first time, it reads until the stream is closed. When you call fill for your second Name_pairs instance, cin has already been closed, so nothing is able to be read, leaving your vectors empty for test1.
Another way to solve the problem would be to call
if(!cin) cin.clear()
to set the istream state back to good.