Printing vector out in functions - c++

I need to print the vector i have filled in listInput. When i go to listPrint the program crashes. What can i do to fix it? Here is my main:
#include <iostream>
#include <string>
#include <vector>
#include "func.h"
using namespace std;
int main(int argc, char** argv) {
subjects a;
int r=1;
while(r!=0){
int select=a.userChoice();
switch(select){
case 1:
a.listPrint();
break;
case 2:
listInput(a);
break;
}
}
return 0;
}
My header:
#ifndef SUBJECT
#define SUBJECT
#include <string>
#include <vector>
class subjects{
private:
std::string subjectName;
std::string lectName;
std::string lectSurname;
int credits;
int studentnum;
public:
/* subjects(){
subjectName="";
lectName="";
lectSurname="";
credits=0;
studentnum=0;
}*/
int userChoice();
int enterNumber(std::string name);
void menu();
std::string getSubjectName(){
return subjectName;
}
std::string getLectName(){
return lectName;
}
std::string getLectSurname(){
return lectSurname;
}
int getCredits(){
return credits;
}
int getStudentNum(){
return studentnum;
}
friend void listInput(subjects a);
void listPrint();
bool checkName(std::string &text);
std::vector<subjects*> entry;
subjects(const std::string subjectName="", const std::string lectName = "", const std::string lectSurname="", const int credits = 0, const int studentnum = 0) :
subjectName(subjectName),
lectName(lectName),
lectSurname(lectSurname),
credits(credits),
studentnum(studentnum){
}
};
#endif
And my function file:
void listInput(subjects a){
.
.
.
a.entry.push_back(new subjects(a.subjectName, a.lectName,a.lectSurname,a.credits, a.studentnum));
}
void subjects::listPrint(){
for(int i=0; i<entry.size(); i++){
cout<<entry[i]->getSubjectName()<<" "<<entry[i]->getLectName()<<" "<<entry[i]->getLectSurname()<<" "<<entry[i]->getCredits()<<" "<<entry[i]->getStudentNum()<<endl;
}
}
I know that using friend functions arent recommended, but i am required to use atleast one of them. Also if i print the vector in listInput, then it only prints the first entry. If there is more than one entry in the vector, it also crashes.

You pass the a instance by value to the list function and then you try to print it. You should consider passing it by reference if you plan to use it outside the scope of the list function.

Related

C++: calling function from vector object in main

I am trying to call printTotals() from main(). I tried person.printTotals() but it does not work because agent only calls functions within the vector STL. I checked other answers, such as C++ Calling Vectors from Function to Main and Using vector of user defined class type objects and How to create a vector of class objects in C++?.
I also checked my STL book, but this case it is not in there.
I have two questions:
Is there a way to call printTotals() outside of the constructor? Can I call it from main()? I want to keep my code clean and modular, but I am unable to access it outside of the constructor.
Each person has 3 neighbors consisting of Persons in a vector. I thought about declaring the neighbors vector like this, but was not sure:
vector<Person> neighbor
For a specific person with id = 3, how can I retrieve their second neighbor's voting status? Would it be:
person[3].neighbor[1].getPersonVotingStatus()?
This is my code:
Person.h
#include <iostream>
#include <string.h>
#include <vector>
class Person
{
public:
Person();
Person( std::vector<Person> person, maxPersons);
std::string getPersonVotingStatus(int ID);
void printTotals();
private:
std::string personName;
float personHeight;
int personID;
std::string isVoter;
vector<Person>neighbor; // <---
}
Person.cpp
#include <iostream>
#include <string.h>
#include <vector>
Person::Person()
{}
Person::Person(int pID, float pHeight, std::string pName, std::string isV)
{
personID = pID;
personHeight = pHeight;
personName = pName;
isVoter = isV;
}
Person::Person( std::vector<Person> person, int maxPersons)
{
for(int = 0; i < maxPersons; i++)
{
person[i].personID = i;
person[i].personHeight = i + 100;
person[i].personName = "testName";
if (i / 2 = 0) {
person[i].isVoter = "yes";
}
else {
person[i].isVoter = "no";
}
}
Person(person[i].personID, person[i].personHeight, person[i].personName, person[i].isVoter);
}
std::String getPersonVotingStatus( int ID)
{
return person[i].isVoter;
}
void printTotals( std::vector<Person> person)
{
int totalVoter = 0;
int totalNonvoter = 0;
for (int i = 0; i< person.size(); i++)
if (person[i].isVoter == "yes") {
totalVoter++;
}
else {
totalNonvoter++;
}
}
main.cpp
#include <iostream>
#include <string.h>
#include <vector>
int main()
{
int maxPersons = 10;
std::vector<Person> person;
Person obj( person, maxPersons);
person.printTotals(); // <--
return 0;
}
Try defining printTotals() as a static function:
class Person
{
public:
static void printTotals(std::vector<Person> person);
}
Then you can call it in main like this:
Person::printTotals(person);

How can I initialize a vector of object pointers while not knowing how many objects will be created?

This code is not running properly as it keeps returning 0xC0000005 on codeblocks and on CMD nothing happens. I checked online and it says I should initialize the vector before I write to it but how can I initialize a vector of objects if I don't know how many objects the user is gonna enter(as it should be increasing the more inputs the user uses).
#include <string>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
class stock {
private:
int sharenumber;
float shareprice;
string sharename;
public:
stock(int x, string y,float z)
:sharenumber(x),sharename(y),shareprice(z)
{
cout<<"An object has been created";
}
string getstring(){
return sharename;
}
};
int toint(char * x){
int y;
y = atoi(x);
return y;
}
string tostring(char * x){
stringstream ss;
string z;
ss<<x;
z = ss.str();
return z;
}
float tofloat(char * x){
float u;
u = atof(x);
return u;
}
int main(int argc, char *argv[])
{
char str1[]= "buy";
vector <stock*> P_obj;
if (strcmp(str1,argv[1]) == 0){
cout<<"this ran"<<endl;
P_obj.push_back(new stock(toint(argv[2]),tostring(argv[3]),tofloat(argv[4])));
cout<<P_obj[0]->getstring();
}
return 0;
}
You should check the number of input before using the input. The argc argument will indicate how many inputs are given as the command line argument (including the first argument, which is typically the name of the executable file).
int main(int argc, char *argv[])
{
char str1[]= "buy";
vector <stock*> P_obj;
if (argc > 1){ // check the number of input
if (strcmp(str1,argv[1]) == 0){
cout<<"this ran"<<endl;
if (argc > 4) { // check the number of input
P_obj.push_back(new stock(toint(argv[2]),tostring(argv[3]),tofloat(argv[4])));
cout<<P_obj[0]->getstring();
} else {
cout<<"too few arguments for "<<str1<<endl;
}
}
} else {
cout<<"no command"<<endl;
}
return 0;
}

Undefined Reference Error/ Dynamically Calling Functions

Hi I am working on a program that involves a Main.cpp, Connect4.cpp, and Connect4.h file. When I compile my program I am getting an error in the Main file saying that my playGame function is an undefined reference. I am compiling both files together(main first) I believe something is wrong in the way I am trying to dynamically call the function playGame. Any input would be much appreciated!
Main.cpp
#include <iostream>
#include <array>
#include "Connect4.h"
void playGame();
using namespace std;
int main()
{
Connect4 *ptr;
ptr=new Connect4;
ptr-> playGame();
delete ptr;
}
Connect4.cpp
#include <iostream>
#include <array>
#include "Connect4.h"
char gameBoard[9][7];
int rows;
int columns;
using namespace std;
void playGame()
{
void display();
int selectColumn(bool);
int tokenPlacement(char token, int columns);
bool winOrLose();
cout<<"Welcome to Connect Four.";
for(int i=0; i<rows;++i)
{
for(int j=0; j<columns; ++j)
{
gameBoard[i][j]=' ';
}
}
bool player1Turn=true;
char winner='n';
int column =0;
while(true){
display();
column=selectColumn(player1Turn);
if(player1Turn==true)
{
tokenPlacement('x',column);
player1Turn=false;
}
else
{
tokenPlacement('o', column);
player1Turn=true;
winner= winOrLose();
if(winner!='n')
{
break;
}
}
cout<<"Winner is:"<<winner;
}
Connect4.h
#ifndef CONNECT4_H_
#define CONNECT4_H_
#include
using namespace std;
class Connect4 {
public:
static void playGame();
private:
void display();
int selectColumn(bool);
int tokenPlacement(char, int);
bool winOrLose();
char gameBoard[9][7];
};
#endif /* CONNECT4_H_ */

Error with strtok Function

In my code i get a unhandled expression error when i use parse function.
In my PopStack function is this the right way to delete the last element of vector.
Error is:
Unhandled exception at 0x0f463b50 (msvcr100d.dll) in Boost_Test.exe: 0xC0000005: Access violation writing location 0x00345d49.
class Stack
{
public:
Stack() {GlobalIndex=0; };
std::vector<char*> v;
int GlobalIndex;
void AddStack(char* txt);
void Parse();
void PopStack();
void PrintStack();
};
void Stack::Parse()
{
char* tok;
tok = strtok(v[GlobalIndex-1], ";");
while(tok!=NULL)
{
cout<<"\nThe time value is = "<<tok<<endl;
tok = strtok(NULL, " ");
}
}
void Stack::AddStack(char* txt)
{
v.push_back(txt);
GlobalIndex++;
}
void Stack::PopStack()
{
v.pop_back();
GlobalIndex--;
}
void Stack::PrintStack()
{
std::cout<<v[GlobalIndex-1]<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i;
Stack s;
s.AddStack("aaa;1.2");
s.AddStack("bbb;1.7;");
s.AddStack("ccc;2.2");
s.Parse(); // This gives a unhandled expression error
s.PopStack();
s.PrintStack();
return 0;
}
The end of the token found, in you case the ';', is replaced by a 0.
This write operation is done on the string literal you pass:
s.AddStack("aaa;1.2");
But the literal is not writable, basically its a 'const char *', hence the access violation.
As advised by other members i have now used c++ strings along with boost library.
#include "stdafx.h"
#include <iostream>
#include <asio.hpp>
#include <regex.hpp>
#include <algorithm/string/regex.hpp>
#include <string>
#include <algorithm/string.hpp>
using namespace std;
class Stack
{
public:
Stack() {GlobalIndex=0; };
std::vector<std::string> v;
string s;
int GlobalIndex;
void AddStack(std::string);
void Parse();
void PopStack();
void PrintStack();
};
void Stack::Parse()
{
std::vector<std::string> result;
boost::split(result,v[GlobalIndex-1],boost::is_any_of(";"));
cout<<"\nThe boost split is = "<<result[1]<<endl;
}
void Stack::AddStack(std::string txt)
{
v.push_back(txt);
GlobalIndex++;
}
void Stack::PopStack()
{
v.pop_back();
cout<<v.size()<<endl;
GlobalIndex--;
}
void Stack::PrintStack()
{
std::cout<<v[GlobalIndex-1]<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i;
Stack s;
s.AddStack("aaaaaa;1.2");
s.AddStack("bbbbb;1.7;");
s.AddStack("ccccc;2.2");
s.Parse();
s.PopStack();
s.PopStack();
s.PrintStack();
cin>>i;
return 0;
}

Passing Pointers to Classes in C++

I am trying to pass a pointer into my classes function, have it incremented, and have the variable retain it's value using pointers. Heres my code, it doesnt increment.
#include "stdafx.h"
#include <iostream>
using namespace std;
class test
{
public:
int addTo();
test(int * currentY);
private:
int y;
};
test::test(int * currentY):
y(*currentY)
{
}
int test::addTo()
{
y++;
return 0;
}
int main ()
{
for (;;)
{
int pointedAt = 1;
int * number = &pointedAt;
test t(number);
t.addTo();
cout <<*number;
char f;
cin >>f;
}
}
This should do it:
#include "stdafx.h"
#include <iostream>
using namespace std;
class test
{
public:
int addTo();
test(int * currentY);
private:
int *y;
};
test::test(int *currentY):
y(currentY)
{}
int test::addTo()
{
++*y;
return 0;
}
int main ()
{
for (;;)
{
int pointedAt = 1;
test t(&pointedAt);
t.addTo();
cout << pointedAt;
}
}
You have to store a pointer to the integer, so it refers to the same address as the original variable.