I'm trying to write a program that takes the grades and prints out the following:
ID:123 NAME:John GRADE:78
but instead I'm getting:
ID:-842150451 NAME: GRADE: 78
Can you guys help me and give me some extra tips to make my code cleaner since I'm fairly new to C++.
Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
Student(int num, string text);
int getID();
void setExamGrade(int a, int b);
int getOverallGrade();
void display();
string getName();
string name;
int id;
int exams[3];
int sum;
int average;
};
#endif
Student.cpp
#ifndef STUDENT_CPP
#define STUDENT_CPP
#include "Student.h"
#include <iostream>
#include <string>
using namespace std;
Student::Student(int num, string text)
{
num = id;
text = name;
exams[0, 1, 2] = 0;
}
int Student::getID() {
return id;
}
string Student::getName() {
return name;
}
void Student::setExamGrade(int a, int b) {
exams[a] = b;
}
int Student::getOverallGrade() {
sum = exams[0] + exams[1] + exams[2];
average = sum / 3;
return average;
}
void Student::display() {
cout << "ID: " << getID();
cout << " NAME: " << getName();
cout << " GRADE: " << getOverallGrade() << endl;
}
#endif
gradebook.cpp
#ifndef GRADEBOOK_CPP
#define GRADEBOOK_CPP
#include "Student.h"
#include <iostream>
using namespace std;
int main() {
Student *s = new Student(123, "John");
s->setExamGrade(0, 80);
s->setExamGrade(1, 60);
s->setExamGrade(2, 95);
s->display();
delete s;
return 0;
}
#endif
You never assign to id in the constructor, hence it's uninitialized and you will have undefined behavior when you print it.
Change
num = id;
to
id = num;
Same with the name.
Also, the statement
exams[0, 1, 2] = 0;
doesn't do what you expect it to do, it only initializes exams[2] to sero, and leaves the rest uninitialized. The expression 0, 1, 2 uses the comma operator.
Either assign to all members of the array separately, or use a constructor member initializer list (which I recommend for all the initialization).
Related
The question:
Why is the following error happening?
definition of implicity-declared 'Clothing::Clothing()
The context:
As an assignment I have to do constructors, destructors and methods in a class Clothing. I'm having a problem when I try to define the constructor in clothing.cpp. I have read that the problem is because I did not declare the constructor in clothing.h, but I think how I have done it, it's declared. I have no clue where the problem lies.
My code:
clothing.h:
#ifndef CLOTHING_H_
#define CLOTHING_H_
#include <string>
#include <iostream>
using namespace std;
class Clothing {
private:
int gender;
int size;
string name;
public:
Clothing();
Clothing(const Clothing &t);
Clothing(int gender, int size, string name);
~Clothing();
int getGender();
int getSize();
string getName();
void setGender(int gender1);
void setSize(int size1);
void setName(string name1);
void print();
void toString();
};
#endif /* CLOTHING_H_ */
clothing.cpp:
#include <iostream>
#include "clothing.h"
#include <string>
#include <sstream>
using namespace std;
Clothing::Clothing() :
gender(1),
size(1),
name("outofstock") {
}
Clothing::Clothing(const Clothing& t) :
gender(t.gender),
size(t.size),
name(t.name) {
}
Clothing::Clothing(int gender, int size, string name) {
}
int Clothing::getGender() {
return gender;
}
int Clothing::getSize() {
return size;
}
string Clothing::getName() {
return name;
}
void Clothing::setGender(int gender1) {
gender = gender1;
}
void Clothing::setSize(int size1) {
size = size1;
}
void Clothing::setName(string name1) {
name = name1;
}
void Clothing::print() {
cout << name << " " << gender << " " << size << endl;
}
void Clothing::toString() {
stringstream ss;
ss << name << " " << gender << " " << size;
cout << ss.str();
}
Errors: \src\clothing.cpp:7:21: error: definition of implicitly-declared 'Clothing::Clothing()'
\src\clothing.cpp:14:37: error: definition of implicitly-declared 'Clothing::Clothing(const Clothing&)'
The error is: you declared a destructor but you didn't define it. Add a definition for the destructor or define it as default:
#ifndef CLOTHING_H_
#define CLOTHING_H_
#include <string>
#include <iostream>
using namespace std;
class Clothing {
private:
int gender;
int size;
string name;
public:
Clothing();
Clothing(const Clothing &t);
Clothing(int gender, int size, string name);
~Clothing() = default; // <-- add a default destructor
int getGender();
int getSize();
string getName();
void setGender(int gender1);
void setSize(int size1);
void setName(string name1);
void print();
void toString();
};
#endif /* CLOTHING_H_ */
After fixing this your code snippet works: tio.run
If you have more problems with your code, the problems are outside of your provided code snippet.
Here is a picture of the error:
I have created a basic class that would hold the information of a sports team. When I am attempting to compare two teams with each other with the this pointer, I am receiving an error. Here are my two files. Hopefully, it is just a simple error.
Team.cpp
#include "Team.h"
#include <string>
#include <sstream>
using namespace std;
Team::Team()
{
teamName = "The Strings";
winNum = 0;
lossNum = 0;
numPlayers = 11;
points = 0;
}
Team::Team(const char newName, int newPlayers)
{
stringstream move;
string strName;
move << newName;
move >> strName;
teamName = strName;
numPlayers = newPlayers;
}
void Team::display() // displays information about the team.
{
cout << "Team name:" << teamName << endl;
cout << "This team has " << numPlayers << " players" << endl;
cout << "This team has " << winNum << " wins and " << lossNum << endl;
}
void Team::addWins() // increment the number of wins
{
winNum = winNum + 1;
}
void Team::addLosses() // increment the number of losses.
{
lossNum = lossNum + 1;
}
void Team::addPlayer(int nrPlayers)
{
numPlayers = numPlayers + nrPlayers;
}
void Team::delPlayers(int nrPlayers)
{
numPlayers = numPlayers - nrPlayers;
}
void Team::setTeam(char name[], int players, int wins, int losses)
{
string strname(name);
teamName = name;
numPlayers = players;
winNum = wins;
lossNum = losses;
}
bool isBetter(const Team &other)
{
if (this->points > other.points)
{
return true;
}
else
{
return false;
}
}
int Team::getWins() // returns the number of wins for a team object
{
return winNum;
}
int Team::getLosses() // returns the number of losses for a team object
{
return lossNum;
}
int Team::getPoints() // returns the number of points a team has
{
points = winNum - lossNum;
return points;
}
Team.h
#ifndef TEAM_H
#define TEAM_H
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
// definition of class Dice
class Team
{
private:
int numPlayers,
winNum,
lossNum;
int points;
string teamName ;
public:
// default constructor: initializes the face of a new
// Dice object to 1
Team();
Team(const char newName, int newPlayers);
void display(); // displays information about the team.
void addWins(); // increment the number of wins
void addLosses(); // increment the number of losses.
void addPlayer(int nrPlayers);
void delPlayers(int nrPlayers);
void setTeam(char name[], int players, int wins, int losses);
bool isBetter(const Team &other);
int getWins(); // returns the number of wins for a team object
int getLosses(); // returns the number of losses for a team object
int getPoints(); // returns the number of points a team has
};
#endif
I can't correctly display information. In the text displayed extra characters. Most likely a problem with the zero character but I was not able to eliminate.
First file: person.h Here I describe a simple class.
#ifndef PERSON_H_INCLUDED
#define PERSON_H_INCLUDED
#include <string>
using std::string;
class Person
{
private:
static const int m_iLIMIT = 25;
string m_sLname; // lastname
char m_cFname[m_iLIMIT]; // firstname
public:
Person () { m_sLname = ""; m_cFname[0] = '\0'; } // #1
Person(const string & sLn, const char * pcFn = "Adam"); // #2
// show lastname и firstname
void Show() const; // format: firstname lastname
void FormalShow() const; // format: lastname, firstname
};
#endif // PERSON_H_INCLUDED
Second file: p_functions.cpp Here I define class methods
#include "person.h"
#include <iostream>
#include <string>
#include <cstring>
using std::string;
using std::cout;
using std::cin;
using std::endl;
// #2
Person::Person(const string & sLn, const char * cFn)
{
m_sLname = sLn;
strcat(m_cFname, cFn);
}
void Person::Show() const
{
cout << "First format: " << m_cFname << ", " << m_sLname << endl;
}
void Person::FormalShow() const
{
cout << "Second format: " << m_sLname << ", " << m_cFname << endl;
}
Third file: main.cpp Here I am testing methods
#include <iostream>
#include "person.h"
using namespace std;
int main()
{
Person one;
Person two("Smith");
Person three("immanuel", "Kant");
one.Show();
one.FormalShow();
two.Show();
two.FormalShow();
three.Show();
three.FormalShow();
return 0;
}
This is the result I get
in the second constructor m_cFname[0] is not initialized with 0
use strcpy instead of strcat
and you will have problem with longer first names
So Ive been learning about classes, and in my main function when I run it, it shows character array members incorrectly.
main program:
#include <iostream>
#include "account.h"
#include "account.cpp"
using namespace std;
int main(){
char num [] = "2435457";
char name [] = "BOB JOE";
account bob(10000, num, name );
bob.show_account();
cout << num; // this should output correctly, but shows the '♦'
return 0;
}
output:
ACCOUNT INFO:
Account holder :
Account number :♦
Balance :10000
♦
Whats weird is that using cout<< directly on the char array num shows the '♦'.
When I copy the char num [] = "2435457" into a new program like:
#include <iostream> //including all the same headers does not affect
#include "account.h" //the output
#include "account.cpp"
using namespace std;
int main(){
char num [] = "2435457";
cout << num;
return 0;
}
It works correctly.
EDITED :
Here is the header "account.h"
#ifndef BANK_H_
#define BANK_H_
using namespace std;
class account {
static const int NMAX = 20, AMAX = 10;
private:
double balance;
char account_number [AMAX];
char account_holder [NMAX];
public:
account(double BAL, char acct [], char name []);
void show_account();
void deposit(double money);
void withdrawl(double money);
};
#endif
And "account.cpp"
#include "account.h"
#include <iostream>
#include <cstring>
using namespace std;
account::account(double BAL, char acct[], char name[]){
strcpy(name, account_holder);
strcpy(acct, account_number);
balance = BAL;
}
void account::show_account(){
cout << "ACCOUNT INFO :"<<endl;
cout << "\tAccount holder :";print(account_holder);
cout << "\n\tAccount number :";print(account_number);
cout << "\n\tBalance :"<<balance<<endl;
}
void account::deposit(double money){
balance += money;
}
void account::withdrawl(double money){
balance -= money;
}
Your problem is in the constructor like I thought.
account::account(double BAL, char acct[], char name[]){
strcpy(name, account_holder);
strcpy(acct, account_number);
balance = BAL;
}
strcpy's reference says:
char* strcpy( char* dest, const char* src );
so you got the 2 parameters switched, you're copying from the uninitialized member array into your char pointer. Since the member array is uninitialized at that point reading from it is undefined behavior. You should switch them:
account::account(double BAL, char acct[], char name[]){
strcpy(account_holder, name);
strcpy(account_number, acct);
balance = BAL;
}
// main.cpp
#include <iostream>
#include <vector>
#include <string>
#include "Student.h"
using namespace std;
void fillVector(vector<Student>&);
void printVector(const vector<Student>&);
int main()
{
vector<Student> myClass;
fillVector(myClass);
printVector(myClass);
return 0;
}
void fillVector(vector<Student>& newMyClass)
{
string name;
char grade;
cout << "How many you students are in your class? ";
int classSize;
cin >> classSize;
for (int i=0; i<classSize; i++)
{
cout<<"Enter student name: ";
cin>>name;
cout<<"Enter student grade: ";
cin>>grade;
Student newStudent(name, grade);
newMyClass.push_back(newStudent);
cout<<endl;
}
cout<<endl;
}
void printVector(const vector<Student>& newMyClass)
{
int size = newMyClass.size();
for ( int i=0; i<size; i++ )
{
cout<<"Student name: "<<newMyClass[i].getName()<<endl;
cout<<"Student grade: "<<newMyClass[i].getGrade()<<endl;
cout<<endl;
}
}
// Student.h
#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student();
Student(string, char);
~Student();
string getName() const;
char getGrade() const;
void setName(string);
void setGrade(char);
private:
string newName;
char newGrade;
};
#endif // STUDENT_H_INCLUDED
// Student.cpp
#include "Student.h"
Student::Student()
{
newGrade = ' ';
}
Student::Student(string name, char grade)
{
newName = name;
newGrade = grade;
}
Student::~Student() {}
string Student::getName() const
{
return newName;
}
char Student::getGrade() const
{
return newGrade;
}
void Student::setName(string name)
{
newName = name;
}
void Student::setGrade(char grade)
{
newGrade = grade;
}
My aim is to declare a class called CreateGradeBook inside Student.hand define it in Student.cpp and put all the code of the main.cpp in it. In other words I want main.cpp to be still there but with no codes in it like below;
#include <iostream>
using namespace std;
int main()
{
}
Please be tolerant if my question is inappropriate or off topic as I'm fairly new with StackOverflow. I've read FAQ section but not all of it.
Well here's a start
class CreateGradeBook
{
public:
void fillVector();
void printVector() const;
private:
vector<Student> myClass;
};
Notice how the vector you declared in main has become a private data member myClass. The two functions you declared have become public methods of CreateGradeBook. Notice also that they have lost their parameters instead they'll now operate on the private data member myClass.
I'll leave you to do the rest.