Staredit Network > Forums > Technology & Computers > Topic: [C++] Problem With Classes, Vectors, Pointers
[C++] Problem With Classes, Vectors, Pointers
Dec 10 2011, 2:19 am
By: Sand Wraith  

Dec 10 2011, 2:19 am Sand Wraith Post #1

she/her

If I attempt to compile the following code, everything works out fine. However, there is a runtime error with running one of the last lines of code which I have highlighted. I'm not sure what is causing it - a hack-job of pointer work or what?

What I'm trying to do is create a vector of CRegularPolygons. Then, using another function, add objects of CRegularPolygons to the vector. Then, in the highlighted line of code, I'm trying to access a function of an object of the vector.

What am I doing wrong? (I suspect it has something to do with how I have attempted to utilize pointers.)


Code
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class CRegularPolygon
{
   string name;
   int numSides;
   float lenSide, apothem;
public:
   CRegularPolygon(string name_, int numSides_, float lenSide_, float apothem_)
   {
       name = name_;
       numSides = numSides_;
       lenSide = lenSide_;
       apothem = apothem_;
   }
   float perimeter()
   {
       return numSides * lenSide;
   }
   float area()
   {
       return 0.5 * numSides * lenSide * apothem;
   }
   float internalAngle()
   {
       return (numSides - 2) / numSides * 180;
   }
   int internalAngleSum()
   {
       return (numSides - 2) * 180;
   }
};

int inputINT(string prompt)
{
   int n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail())
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

float inputFLOAT(string prompt)
{
   float n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail())
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

void createRegularPolygons(vector<CRegularPolygon> regPolys)
{
   string name;
   int numSides;
   float lenSide, apothem;
   string createRegPoly;
   do
   {
       cout << "Create a new regular polygon? (y/n)" << endl;
       cin >> createRegPoly;
       if(createRegPoly == "y")
       {
           // gather statistics of polygon
           cout << "Enter ID/name of polygon:" << endl;
           cin >> name;
           numSides = inputINT("Enter number of sides:\n");
           lenSide = inputFLOAT("Enter length of one side:\n");
           apothem = inputFLOAT("Enter apothem\n(the line segment from the center of the regular polygon to the\nmidpoint of a side):\n");
           regPolys.push_back(CRegularPolygon(name, numSides, lenSide, apothem)); // create polygon
       }
   } while(createRegPoly == "y");
}

int main()
{  
   vector<CRegularPolygon> regularPolygons;
   vector<CRegularPolygon> *regPolys = &regularPolygons;
   createRegularPolygons(*regPolys);
   cout << (regularPolygons.at(0).internalAngle()) << endl; // PROBLEMATIC LINE
   system("PAUSE");
   return 0;
}


EDIT:

nvm I fixed my pointer work I think

Code
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class CRegularPolygon
{
   string name;
   int numSides;
   float lenSide, apothem;
public:
   CRegularPolygon(string name_, int numSides_, float lenSide_, float apothem_)
   {
       name = name_;
       numSides = numSides_;
       lenSide = lenSide_;
       apothem = apothem_;
   }
   float perimeter()
   {
       return numSides * lenSide;
   }
   float area()
   {
       return 0.5 * numSides * lenSide * apothem;
   }
   float internalAngle()
   {
       return (numSides - 2) / numSides * 180;
   }
   int internalAngleSum()
   {
       return (numSides - 2) * 180;
   }
};

int inputINT(string prompt)
{
   int n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail())
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

float inputFLOAT(string prompt)
{
   float n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail())
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

void createRegularPolygons(vector<CRegularPolygon> *regPolys)
{
   string name;
   int numSides;
   float lenSide, apothem;
   string createRegPoly;
   do
   {
       cout << "Create a new regular polygon? (y/n)" << endl;
       cin >> createRegPoly;
       if(createRegPoly == "y")
       {
           // gather statistics of polygon
           cout << "Enter ID/name of polygon:" << endl;
           cin >> name;
           numSides = inputINT("Enter number of sides:\n");
           lenSide = inputFLOAT("Enter length of one side:\n");
           apothem = inputFLOAT("Enter apothem\n(the line segment from the center of the regular polygon to the\nmidpoint of a side):\n");
           regPolys->push_back(CRegularPolygon(name, numSides, lenSide, apothem)); // create polygon
       }
   } while(createRegPoly == "y");
}

int main()
{  
   vector<CRegularPolygon> regularPolygons;
   vector<CRegularPolygon> *regPolys = &regularPolygons;
   createRegularPolygons(regPolys);
   cout << regularPolygons.at(0).internalAngle() << endl;
   system("PAUSE");
   return 0;
}


Could someone explain to me what I was doing wrong at first?

EDIT2:

Also, are there commands/functions that returns the maximum values of int, float, double, etc.?

Post has been edited 2 time(s), last time on Dec 10 2011, 2:34 am by Sand Wraith.




Dec 10 2011, 2:43 am Lanthanide Post #2



It's because in your first lot of code you are dereferencing the regPoly's pointer and passing it to the function that expects a CRegularPolygon object.

In the second you have corrected this so that the function takes a pointer to a CRegularPolygon object, and that is what you have passed to it in your call.

Explainly this clearly is kind of tricky in this case since you're using an object type, if it were just an integer it'd be easier to explain.

For C++ I found this: http://www.cplusplus.com/reference/std/limits/numeric_limits/

In C you'd probably just need a .h file that had all the limits defined using macros. Something I found suggested that the ones for doubles etc are in float.h.



None.

Dec 10 2011, 2:48 am CecilSunkure Post #3



Quote from Sand Wraith
Also, are there commands/functions that returns the maximum values of int, float, double, etc.?
You can use sizeof. It returns the amount of bytes one would take. So then convert that to a data range (for unsigned) by using range = 0 through 2^n for n representing the number of bits. So one byte is 8 bits, or 0-255 (a character). Then if float is 4 bytes, that would be 32 bits in total, or 4294967295. You can also google the value ranges.

Usually it goes float 4, char 1, short 2, double 8, int 4 bytes.



None.

Dec 10 2011, 3:50 am Sand Wraith Post #4

she/her

Thanks for the responses.

I'm having more trouble with my code, again at runtime.

The line of code I'm having trouble at is highlighted with "// PROBLEM LINE".

What I'm trying to do is output a chart displaying the statistics of all of the polygons.

The program crashes when I try to output the statistics.

Here is the error Devcpp is giving me:
136 E:\C++ Projects\regular polygon\main.cpp [Warning] cannot pass objects of non-POD type `struct std::string' through `...'; call will abort at runtime

I'm guessing I can't use printf in this scenario, but I don't know how to otherwise limit the outputted data to 8 character spaces to keep the table intact.

Code
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class CRegularPolygon
{
public:
   string name;
   int numSides;
   float lenSide, apothem;
   CRegularPolygon(string name_, int numSides_, float lenSide_, float apothem_)
   {
       name = name_;
       numSides = numSides_;
       lenSide = lenSide_;
       apothem = apothem_;
   }
   float perimeter()
   {
       return numSides * lenSide;
   }
   float area()
   {
       return 0.5 * numSides * lenSide * apothem;
   }
   float internalAngle()
   {
       return (numSides - 2) / numSides * 180;
   }
   int internalAngleSum()
   {
       return (numSides - 2) * 180;
   }
};

int inputINT(string prompt, int min, int max)
{
   int n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail() || n < min || n > max)
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

float inputFLOATx(string prompt, float min, float max)
{
   float n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail() || n <= min || n >= max)
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

void createRegularPolygons(vector<CRegularPolygon> *regPolys)
{
   string name;
   int numSides;
   float lenSide, apothem;
   string createRegPoly;
   do
   {
       cout << "Create a new regular polygon? (y/n)" << endl;
       cin >> createRegPoly;
       if(createRegPoly == "y")
       {
           // gather statistics of polygon
           cout << "Enter ID/name of polygon (name <= 8 characters please):" << endl;
           cin >> name;
           numSides = inputINT("Enter number of sides (3 <= n <= 99999999):\n", 3, 99999999);
           lenSide = inputFLOATx("Enter length of one side (0 < n < 99999999)\n", 0, 99999999);
           apothem = inputFLOATx("Enter apothem\n(the line segment from the center of the regular polygon to the\nmidpoint of a side) (0 < n < 99999999):\n", 0, 99999999);
           regPolys->push_back(CRegularPolygon(name, numSides, lenSide, apothem)); // create polygon
       }
   } while(createRegPoly == "y");
}

int main()
{  
   vector<CRegularPolygon> regularPolygons;
   vector<CRegularPolygon> *regPolys = &regularPolygons;
   int inMain;
   int inDel;
   do
   {
       // Main menu
       system("CLS");
       cout << "\tMENU" << endl;
       cout << "[0] Quit" << endl;
       cout << "[1] Create New Regular Polygons" << endl;
       cout << "[2] Reset" << endl;
       cout << "[3] Delete a Polygon" << endl;
       cout << "[4] View All Polygons" << endl;
       inMain = inputINT(">> ", 0, 9001);
       switch(inMain)
       {
           case 1:
               createRegularPolygons(regPolys);
               break;
           case 2:
               regPolys->clear();
               break;
           case 3:
               inDel = inputINT(">> ", 0, regPolys->size() - 1);
               regPolys->erase(regPolys->begin() - 1 + inDel);
               break;
           case 4:
               cout << "ID      |Name    |numSides|lenSide |apothem " << endl;
               cout << "--------+--------+--------+--------+--------" << endl;
               for(int i = 0; i < regPolys->size(); i++)
               {
                   printf("%8|%8|%8|%8|%8\n", i, regPolys->at(i).name, regPolys->at(i).numSides, regPolys->at(i).lenSide, regPolys->at(i).apothem); // PROBLEM LINE
               }
               system("PAUSE");
               break;
       }
   } while(inMain != 0);
   return 0;
}





Dec 10 2011, 4:13 am Lanthanide Post #5



What is %8 supposed to be in your printf?

Integers should be %i, strings %s, float is %f. I don't know what %8 is.

http://www.cplusplus.com/reference/clibrary/cstdio/printf/

Maybe you wanted %8i | %8s | %8i | %8f | %8f ?



None.

Dec 10 2011, 4:16 am Sand Wraith Post #6

she/her

%8 is supposed to be the field width.

I managed to hack up a work-around.

Code
cout << "ID      |Name    |numSides|lenSide |apothem " << endl;
               cout << "--------+--------+--------+--------+--------" << endl;
               for(int i = 0; i < regPolys->size(); i++)
               {
                   cout.width(8);
                   cout << right << i << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).name << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).numSides << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).lenSide << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).apothem << endl;
                   //printf("%8u|%8s|%8u|%8g|%8g\n", i, regPolys->at(i).name, regPolys->at(i).numSides, regPolys->at(i).lenSide, regPolys->at(i).apothem);
               }





Dec 10 2011, 4:18 am Lanthanide Post #7



Printf should work, you were just using it wrong.



None.

Dec 10 2011, 5:24 am Sand Wraith Post #8

she/her

Well, I tried
Quote
%8i | %8s | %8i | %8f | %8f
but it didn't work.




Dec 10 2011, 6:04 am Lanthanide Post #9



Probably because name is a string type, rather than character array. You could do multiple calls to printf on different lines, each calling a separate part. Then the bit that fails will be obvious.



None.

Dec 10 2011, 6:18 am Sand Wraith Post #10

she/her

Okay, thanks. I will try that tomorrow or whenever I have time.

For now, here is the fruit of my efforts.

Code
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class CRegularPolygon
{
public:
   string name;
   int numSides;
   float lenSide, apothem;
   CRegularPolygon(string name_, int numSides_, float lenSide_, float apothem_)
   {
       name = name_;
       numSides = numSides_;
       lenSide = lenSide_;
       apothem = apothem_;
   }
   float perimeter()
   {
       return numSides * lenSide;
   }
   float area()
   {
       return 0.5 * numSides * lenSide * apothem;
   }
   float internalAngle()
   {
       return (numSides - 2) / numSides * 180;
   }
   int internalAngleSum()
   {
       return (numSides - 2) * 180;
   }
};

int inputINT(string prompt, int min, int max)
{
   int n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail() || n < min || n > max)
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

float inputFLOATx(string prompt, float min, float max)
{
   float n;
   bool bad = 1;
   do
   {
       cout << prompt;
       cin >> n;
       if (cin.fail() || n <= min || n >= max)
       {
           cout << "ERROR: Invalid input." << endl;
           cin.clear();
           cin.ignore(numeric_limits<int>::max(),'\n');
       }
       else
           bad = 0;
   } while (bad);
   return n;
}

void createRegularPolygons(vector<CRegularPolygon> *regPolys, int location = 0)
{
   string name;
   int numSides;
   float lenSide, apothem;
   string createRegPoly;
   if(location == 0) // called by create
   {
       do
       {
           cout << "Create a new regular polygon? (yes or anything else to stop)" << endl;
           cin >> createRegPoly;
           if(createRegPoly == "y")
           {
               // gather statistics of polygon
               cout << "Enter ID/name of polygon (name <= 8 characters please):" << endl;
               cin >> name;
               numSides = inputINT("Enter number of sides (3 <= n <= 99999999):\n", 3, 99999999);
               lenSide = inputFLOATx("Enter length of one side (0 < n < 99999999)\n", 0, 99999999);
               apothem = inputFLOATx("Enter apothem\n(the line segment from the center of the regular polygon to the\nmidpoint of a side) (0 < n < 99999999):\n", 0, 99999999);
               regPolys->push_back(CRegularPolygon(name, numSides, lenSide, apothem)); // create polygon
           }
       } while(createRegPoly == "y");
   }
   else // called by modify
   {
       // gather statistics of polygon
       cout << "Enter ID/name of polygon (name <= 8 characters please):" << endl;
       cin >> name;
       numSides = inputINT("Enter number of sides (3 <= n <= 99999999):\n", 3, 99999999);
       lenSide = inputFLOATx("Enter length of one side (0 < n < 99999999)\n", 0, 99999999);
       apothem = inputFLOATx("Enter apothem\n(the line segment from the center of the regular polygon to the\nmidpoint of a side) (0 < n < 99999999):\n", 0, 99999999);
       regPolys->insert(regPolys->begin() + location, CRegularPolygon(name, numSides, lenSide, apothem)); // create polygon/
   }
}

int main()
{  
   vector<CRegularPolygon> regularPolygons;
   vector<CRegularPolygon> *regPolys = &regularPolygons;
   int inMain;
   int inDel;
   int inDelR1, inDelR2;
   int inMod;
   do
   {
       // Main menu
       system("CLS");
       cout << "\tREGULAR POLYGONS::MENU" << endl;
       cout << "[0] Quit" << endl;
       cout << "[1] Reset" << endl;
       cout << "[2] View All Polygons" << endl;
       cout << "[3] Create New Polygons" << endl;
       cout << "[4] Modify a Polygon" << endl;
       cout << "[5] Delete a Polygon" << endl;
       cout << "[6] Delete X to Y Polygons" << endl;
       inMain = inputINT(">> ", 0, 9001);
       switch(inMain)
       {
           // case 0: Quit
           case 1: // Reset
               regPolys->clear();
               break;
           case 2: // View all
               cout << "ID      |Name    |numSides|lenSide |apothem " << endl;
               cout << "--------+--------+--------+--------+--------" << endl;
               for(int i = 0; i < regPolys->size(); i++)
               {
                   cout.width(8);
                   cout << right << i << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).name << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).numSides << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).lenSide << "|";
                   cout.width(8);
                   cout << right << regPolys->at(i).apothem << endl;
                   //printf("%8u|%8s|%8u|%8g|%8g\n", i, regPolys->at(i).name, regPolys->at(i).numSides, regPolys->at(i).lenSide, regPolys->at(i).apothem);
               }
               system("PAUSE");
               break;
           case 3: // Create
               createRegularPolygons(regPolys);
               break;
           case 4: // Modify
               if(regPolys->size() != 0)
               {
                   cout << "IDs 0 to " << regPolys->size() - 1 << " are valid." << endl;
                   inMod = inputINT("Modify ID: ", 0, regPolys->size() - 1);
                   regPolys->erase(regPolys->begin() + inMod);
                   createRegularPolygons(regPolys, inMod);
               }
               else
               {
                   cout << "There are no polygons to modify." << endl;
                   system("PAUSE");
               }
               break;
           case 5: // Delete
               if(regPolys->size() != 0)
               {
                   cout << "IDs 0 to " << regPolys->size() - 1 << " are valid." << endl;
                   inDel = inputINT("Delete ID: ", 0, regPolys->size() - 1);
                   regPolys->erase(regPolys->begin() + inDel);
               }
               else
               {
                   cout << "There are no polygons to delete." << endl;
                   system("PAUSE");
               }
               break;
           case 6: // Delete range
               if(regPolys->size() != 0)
               {
                   cout << "IDs 0 to " << regPolys->size() - 1 << " are valid." << endl;
                   inDelR1 = inputINT("X = ", 0, regPolys->size() - 1);
                   inDelR2 = inputINT("Y = ", 0, regPolys->size() - 1);
                   if(inDelR1 > inDelR2)
                   {
                       cout << "ERROR: X > Y!" << endl;
                   }
                   else
                   {
                       regPolys->erase(regPolys->begin() + inDelR1, regPolys->begin() + inDelR2);
                   }
               }
               else
               {
                   cout << "There are no polygons to delete." << endl;
                   system("PAUSE");
               }
               break;
       }
   } while(inMain != 0);
   return 0;
}





Dec 10 2011, 8:39 pm Sand Wraith Post #11

she/her

Quote from Lanthanide
Probably because name is a string type, rather than character array. You could do multiple calls to printf on different lines, each calling a separate part. Then the bit that fails will be obvious.

I did this, and as it turns out, you were right; the string was messing up the printf function.

I'm going to use cout.




Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[10:05 am]
Moose -- ya
[05:23 am]
zsnakezz -- yes
[2024-5-12. : 8:51 pm]
l)ark_ssj9kevin -- Are you excited for Homeworld 3?
[2024-5-12. : 8:44 pm]
l)ark_ssj9kevin -- Hi Brusilov
[2024-5-12. : 4:35 pm]
O)FaRTy1billion[MM] -- Brusilov
Brusilov shouted: Hey, what happened to EUDDB? Is there a mirror for it somewhere? Need to do a little research.
my server that was hosting it died
[2024-5-10. : 8:46 pm]
NudeRaider -- Brusilov
Brusilov shouted: Hey, what happened to EUDDB? Is there a mirror for it somewhere? Need to do a little research.
https://armoha.github.io/eud-book/
[2024-5-10. : 8:36 am]
Brusilov -- Hey, what happened to EUDDB? Is there a mirror for it somewhere? Need to do a little research.
[2024-5-09. : 11:31 pm]
Vrael -- :wob:
[2024-5-09. : 8:42 pm]
Ultraviolet -- :wob:
[2024-5-08. : 10:09 pm]
Ultraviolet -- let's fucking go on a madmen rage bruh
Please log in to shout.


Members Online: lil-Inferno, Roy