I am doing my first C++ program for my class. I am really new to this program so I have a lot to learn. In my program I am suppose to create a Student class with Undergrad/grad/gradassist derived classes. The name and SSN fields have to be in a char array (I know string makes more sense but the teacher demands a char array). The program mostly works fine except it does not print anything in my char arrays. Please help!
#include <iostream>;
using namespace std;
class Student {
protected:
char name[21];
char ssn[10];
float gpa;
int credits;
public:
Student::Student() {};
Student(const char n[], const char ss[], float& gp, int& cred) {
name[21] = n[21];
ssn[10] = ss[10];
gpa = gp;
credits = cred;
}
virtual void print() {
cout << "Name: " << name << endl;
cout << "SSN: " << ssn << endl;
cout << "GPA: " << gpa << endl;
cout << "Credits: " << credits << endl;
}
virtual float tuition() const = 0;
};
class undergrad : public Student {
protected:
float undergrad_rate;
char* year;
public:
undergrad::undergrad() {}
undergrad(float ugr, char* yr, const char n[], const char ss[], float&
gp, int& cred) :
Student(n, ss, gp, cred), undergrad_rate(ugr), year(yr){}
void set_year(char* yr) {
year = yr;
}
char* getYear() {
return year;
}
float getRate() {
return undergrad_rate;
}
void print() {
Student::print();
cout << "Undergrad rate: " << undergrad_rate << endl;
cout << "year: " << year << endl;
}
float tuition() {
//cout << "The tuition is $35000" << endl;
return 35000;
}
};
class grad : public Student {
protected:
float grad_rate;
char* thesis;
public:
};
int main(){
char* jr = "Junior";
char* sr1 = "Senior";
char* fr = "Freshman";
char* sr = "Sophmore";
undergrad g(380, jr, "M", "000111222", 4.0, 12);
g.print();
system("pause");
return 0;
}
The problem lies here, in the way you initialize the members name and ssn:
Student(const char n[], const char ss[], float& gp, int& cred) {
name[21] = n[21];
ssn[10] = ss[10];
There's more than one thing wrong here
name and ssn are char arrays of size 21 and size 10 respectively. This means that valid indices range from 0 to 20 and 0 to 9 respectively. So by accessing name[21] and ssn[10] you're accessing elements past the end of the allotted memory.
Even if the indices were valid, you would just be assigning a single character by doing it this way.
In order to initialize these member variables the way you're intending, do this:
Student(const char n[], const char ss[], float& gp, int& cred) {
strcpy_s(name, sizeof(name), n);
strcpy_s(ssn, sizeof(ssn), ss);
This will copy all the characters comprising the input strings into your member variables and you will get the desired output.
Related
I can print the correct value in setter function but when I try to return the same variable using getter there is no output. Here is my code. Anyone has idea on how I correct my code?
class Student {
public:
char age;
double height;
double gpa;
int getAge();
void setAge(int *);
protected:
const char * name;
};
class Male :Student {
public:
void setName(const char * s);
const char * getName();
};
void Male::setName(const char * s){
const char* name = s;
std::cout << name << std::endl;
}
const char* Male::getName() {
return name; //I can't return the value of variable name.
std::cout << name << std::endl;
}
void Student::setAge(int* c) {
age = *c;
}
int Student::getAge() {
return age;
}
int main() {
Student jason;
Male myName;
int edad = 30;
jason.height = 162;
jason.gpa = 1.5;
jason.setAge(&edad);
myName.setName("James");
std::cout << jason.height << "\n" << jason.getAge() << "\n" << jason.gpa << "\n" << std::endl;
system("pause");
return 0;
}
I don't know why I can't return the const char variable. :(
void Male::setName(const char * s) {
name = s;
std::cout << name << std::endl;
}
You need to set s to the member variable name instead of creating a local variable in the method
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I need help debugging this code for a class. I am not a computer science major, so I need explanation in very basic terms. The error code I'm getting is error LNK2019: unresolved external symbol "public: void __thiscall Student::showStudent(void)" (?showStudent#Student##QAEXXZ) referenced in function _main
I don't understand what this means. Can someone explain please?
#include<iostream>
#include<string.h>
using namespace std;
//Added namespace
class Person
{
public:
char initial;
Person(const int id, const int a, const char i);
//Renamed function Person
void showPerson();
int idNum;
int age;
};
Person::Person(const int id, const int a, const char i)
{
idNum = id;
age = a;
initial = i;
};
void Person::showPerson(void)
{
cout << "Person id#: " << idNum << " Age: " << age << " Initial: " << initial;
//Added << to the correct places
}
class Student
{
public:
Student (const int id, const int a, const char i, const double gpa);
void showStudent();
double gpa;
int idNum;
int age;
char initial;
};
Student::Student(const int id, const int a, const char i, const double gradePoint)
{
Person::Person(id, a, i);
gpa = gradePoint;
};
void showStudent(Student student)
{
cout << "Student ID# " << student.idNum;
cout << " Avg: " << student.gpa << endl;
cout << "Person id#: " << student.idNum << " Age: " << student.age << " Initial: " << student.initial;
cout << endl << " Age: " << student.age << ".";
cout << " Initial: " << student.initial << endl;
};
void main()
{
Person per(387, 23, 'A');
//Put two lines into one
cout << endl << "Person..." << endl;
per.showPerson();
Student stu(388, 18, 'B', 3.8);
cout << endl << endl << "Student..." << endl;
stu.showStudent();
system("pause");
}
It's giving me a LNK2019 error? Help please!
Adding to AndyG's answer. Your Student class should inherit from Person. Like so:
class Student : public Person {
/* members */
};
Because in your Student constructor you're calling Person::Person(id, a, i); and this will not set your Student attributes idNum, age and initial, because you've redefined them in Student and you're calling the Person ctor without initialising it to anything.
To make your code more cohesive and reusable I would define the classes like this:
class Person {
protected:
char initial;
int idNum;
int age;
public:
Person(const int id, const int a, const char i);
void showPerson();
};
class Student : public Person {
private:
double gpa;
public:
Student (const int id, const int a, const char i, const double gpa);
void showStudent();
};
In this way your Student instances have all of the protected member attributes (id, age and initial) from the Person class and this defines a Student is a Person. This is part of Object Oriented Programming (OOP) paradigm.
So you set your Student constructor like this:
Student::Student(const int& id, const int& a, const char& i, const double& gradePoint) {
idNum = id; // This works because Student inherits from Person, so it has all its attributes!
age = a;
initial = i;
gpa = gradePoint;
};
And now you shouldn't have errors and you have a clean, reusable OOP solution at hand. You could now, for instance, have a Teacher which also inherits (is a generalisation of) from Person and it will have Person's attributes.
i am trying to input a string in my code in c++ and when i run i always get the following error: Exception thrown at 0x0F5023F5 (msvcp140d.dll) in assignment-1.exe: 0xC0000005: Access violation writing location 0x00229C20. i will post my code below if anyone could help me that would be great.Please note that i already know that its a problem with me trying to access the memory location on which you dont have access to, i just dont know how to fix it.
HEADER FILE:
#ifndef item_H
#define item_h
class item
{
private:
//attributes
int itemID;
char itemName[20];
float itemcost;
float itemprice;
//utility function
float calcPrice();
public:
//constructor
item(int = 000, char[] = "itemUnknown", float = 0,float = 0);
//destructor
~item();
//set functions
void setAll(int, char[], float, float);
void setID(int);
void setName(char[]);
void setCost(float);
//get function
int getID();
float getcost();
float getprice();
void getname();
//print function
void print();
};
#endif
CPP:
#include "Dariush.h"
#include <iostream>
#include <iomanip>
#include<string>
using namespace std;
//constructor will set attributes
item::item(int ID, char n[] , float c,float p)
{
setID(ID);
setName(n);
setCost(c);
setAll(ID, n, c, p);
}
//destructor will print destroing two objects
item::~item()
{
cout << "destroing two objects : " << " " << itemName << " "
<< " & " << itemName << endl;
}
//set functions :
void item::setID(int ID)
{
cout << "please enter the item's ID : " << endl;
cin >> ID;
}
void item::setName(char n[])
{
cout << "please enter the item's name" << endl;
cin.ignore();
cin.getline(n, 20);
}
void item::setCost(float c)
{
cout << "please enter the item's cost : " << endl;
cin >> c;
}
void item::setAll(int ID, char n[], float c, float p)
{
itemID = (ID > 0 && ID < 999) ? ID : 0;
strcpy_s(itemName, n);
itemcost = (c > 0) ? c : 0;
calcPrice();
}
//get functions :
int item::getID()
{
return itemID;
}
float item::getcost()
{
return itemcost;
}
float item::getprice()
{
return itemprice;
}
void item::getname()
{
cout << itemName << endl;
}
//print function :
void item::print()
{
cout << "ID : " << itemID << endl
<< "Name : " << itemName << endl
<< "cost : " << itemcost << endl
<< "price : " << itemprice << endl;
}
// utility function for price callculation :
float item::calcPrice()
{
if (itemcost < 1000)
{
itemprice = itemcost + (itemcost*0.1);
}
else
itemprice = itemcost + (itemcost*0.2);
return itemprice;
}
MAIN.CPP:
#include "Dariush.h"
#include <iostream>
#include<string>
using namespace std ;
void main()
{
item i1;
item i2;
i1.print();
i2.print();
}
thanks for the assistance.
Lets take a closer look at these three function declarations:
item(int = 000, char[] = "itemUnknown", float = 0,float = 0);
void setAll(int, char[], float, float);
void setName(char[]);
The thing here is that the character "array" arguments you declare are not really arrays at all. Instead they are pointers. When declaring arguments, e.g. char n[] is actually translated by the compiler as char *n.
The constructor declaration makes the pointer point to the constant string literal "". And the important thing about constant string literals is that they are indeed constant. Trying to modify a string literal leads to undefined behavior. And change this literal is what you are trying to do with the cin.getline(n, 20) call in the setName function. Not only that, but you are also telling the cin.getline function to read more than fits in the string literal.
The simple solution is to have setName read into the member variable itemName instead.
There are many problems with this code, but the one that is causing the access violation is:
void item::setName(char n[])
{
cout << "please enter the item's name" << endl;
cin.ignore();
cin.getline(n, 20); //here
}
You should use cin.getline(itemName, 20); instead.
Also, to prevent such error in the future, declare arguments as char const n[] instead of char n[] - good compiler should display a warning when you use string literals with non-const pointer as argument.
My program is returning garbage values for variables modeled as c-strings. The program uses a class to model datatype Song. It appears the error would occur when the variable is set.
Inputs to the program and the outputs are listed below.
My apologies for the length of the code.
Why the random values?
Code
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_CHAR = 100;
class Song
{
public:
//Default constructor
Song();
//Constructor
Song(char title[], char artist[], char album[], int min, int sec);
//Destructor
~Song();
//Accessor functions
char getTitle()const;
char getArtist() const;
char getAlbum() const;
int getMin() const;
int getSec() const;
//Mutator functions
void setTitle(const char*);
void setArtist(const char*);
void setAlbum(const char*);
void setMin(int);
void setSec(int);
private:
//Member Variables
char title[MAX_CHAR];
char artist[MAX_CHAR];
char album[MAX_CHAR];
int min;
int sec;
};
Song::Song(){}
Song::Song(char newTitle[],char newArtist[],char newAlbum[], int newMin, int newSec)
{
strncpy(title, newTitle, 100);
strncpy(artist, newArtist, 100);
strncpy (album, newAlbum, 100);
min = newMin;
sec = newSec;
}
Song::~Song(){}
//getter functions
char Song::getTitle() const
{
return title[MAX_CHAR];
}
char Song::getArtist() const
{
return artist[MAX_CHAR];
}
char Song::getAlbum() const
{
return album[MAX_CHAR];
}
int Song::getMin() const
{
return min;
}
int Song::getSec() const
{
return sec;
}
//setter functions
void Song::setTitle(const char newTitle[])
{
strcpy(title, newTitle);
}
void Song::setArtist(const char newArtist[])
{
strcpy(artist, newArtist);
}
void Song::setAlbum(const char newAlbum[])
{
strcpy(album, newAlbum);
}
void Song::setMin(int min)
{
this->min = min;
}
void Song::setSec(int sec)
{
this->sec = sec;
}
int main ()
{
char newTitle[MAX_CHAR];
char newArtist[MAX_CHAR];
char newAlbum[MAX_CHAR];
int min;
int sec;
cout << "Enter title: ";
cin >> newTitle;
cout << "Enter artist: ";
cin >> newArtist;
cout << "Enter album: ";
cin >> newAlbum;
cout << "Enter minutes: ";
cin >> min;
cout << "Enter seconds: ";
cin >> sec;
Song song;
song.setTitle(newTitle);
song.setArtist(newArtist);
song.setAlbum(newAlbum);
song.setMin(min);
song.setSec(sec);
cout << endl << "Title: " << song.getTitle() << endl <<
"Artist: " << song.getArtist() << endl <<
"Album: " << song.getAlbum() << endl <<
"Minutes: " << song.getMin() << endl <<
"Seconds: " << song.getSec() << endl;
return 0;
}
I/O
The inputs and the erroneous values that are consistently returned:
//Inputs
Enter title: title
Enter artist: artist
Enter album: album
Enter minutes: 3
Enter seconds: 20
//Outputs
Title: a
Artist: a
Album:
Minutes: 3
Seconds: 20
The problem is in your getter member functions where you actually return a character and not the array. You need to do the following changes:
const char* getTitle() const;
const char* getArtist() const;
const char* getAlbum() const;
const char* Song::getTitle() const {
return title;
}
const char* Song::getArtist() const {
return artist;
}
const char* Song::getAlbum() const {
return album;
}
My output name is not being displayed in my program. I have been looking at the code and
I just can't find my error
input
name : John Dough
id : 123445
start date : 10312014
shift: 2
output
name : ^^^^^^ <<<< I am having problem my name not being displayed
id : 123445
start date : 10312014
shift : 2
code
//This program demostrates a class and a derived class with constructors.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Employee
{
private:
char EmpName;
int EmpNum;
int HireDate;
public:
void setEmpName(char);
void setEmpNum(int);
void setHireDate(int);
char getEmpName() const;
int getEmpNum() const;
int getHireDate() const;
Employee();
};
void Employee::setEmpName(char x)
{
EmpName = x;
}
void Employee::setEmpNum(int y)
{
EmpNum = y;
}
void Employee::setHireDate(int z)
{
HireDate = z;
}
char Employee::getEmpName() const
{
return EmpName;
}
int Employee::getEmpNum() const
{
return EmpNum;
}
int Employee::getHireDate() const
{
return HireDate;
}
Employee::Employee()
{
cout << "I will ask you some questions about an employee.\n\n";
}
class ProductionWorker : public Employee
{
private:
int Shift;
double HourlyPayRate;
public:
void setShift(int);
void setHourlyPayRate(double);
int getShift() const;
double getHourlyPayRate() const;
ProductionWorker();
};
void ProductionWorker::setShift(int a)
{
Shift = a;
}
void ProductionWorker::setHourlyPayRate(double b)
{
HourlyPayRate = b;
}
int ProductionWorker::getShift() const
{
return Shift;
}
double ProductionWorker::getHourlyPayRate() const
{
return HourlyPayRate;
}
ProductionWorker::ProductionWorker()
{
cout << "After answering the questions,\n";
cout << "I will display the employee's information.\n\n\n";
}
int main()
{
ProductionWorker info;
char name[100];
int num;
int date;
int shift;
double rate;
cout << "What is the employee's name? ";
cin.getline(name, 100);
cout << "What is the employee's number? ";
cin >> num;
cout << "What is the employee's hire date?\n";
cout << "(Month, day, and year without any slashes,\n";
cout << "dashes, commas, or other punctuation.)\n";
cout << "For example, January 14, 1983 would look like 01141983. ";
cin >> date;
cout << "Does the employee work shift 1 or shift 2? ";
cin >> shift;
cout << "How much does the employee make per hour? ";
cin >> rate;
info.setEmpName(name[100]);
info.setEmpNum(num);
info.setHireDate(date);
info.setShift(shift);
info.setHourlyPayRate(rate);
cout << "\n\nHere is the employee's data:\n\n";
cout << "Employee's Name: " << info.getEmpName() << endl;
cout << "Employee's Number: " << info.getEmpNum() << endl;
cout << "Employee's Hire Date: " << info.getHireDate() << endl;
cout << "Employee's Shift: " << info.getShift() << endl;
cout << setprecision(2) << fixed;
cout << "Employee's Hourly Pay Rate: $" << info.getHourlyPayRate() << endl << endl;
return 0;
}
This is wrong: you're accessing an out-of-range character instead of passing the array to the function
char name[100];
//.. initialize name..
info.setEmpName(name[100]); // Accesses the 100th character (out-of-range [0-99])
void Employee::setEmpName(char x)
{
EmpName = x;
}
I would go for using std::string by changing EmpName (also wrong, it's not a single character) to a std::string
class Employee
{
private:
string EmpName;
int EmpNum;
int HireDate;
public:
void setEmpName(std::string& name);
void setEmpNum(int);
void setHireDate(int);
string getEmpName() const;
int getEmpNum() const;
int getHireDate() const;
Employee();
};
Also don't forget to change char name[100] to a std::string in the main function.
Live Example
You can of course accomplish this also with char arrays, in that case if you intend to use a fixed-size array you could either pass it by reference or just copy the content of a pointer to the array into a memory array for Employee.
There are multiple problems with your code.
First, the data type of Employee::EmpName should not be char. It should be a char array or even better would be a std::string.
Second the parameter of the setEmpName function should be either a const char* or a const std::string&.
Third, the name variable should perhaps be a std::string instead of a char array. Of course if you make that change the parameter of the setEmpName function should be const std::string&.
Fourth, when calling the setEmpName function you should just call it as follows: info.setEmpName(name).
Next, you should use std::getline(cin, name) instead of cin.getline(name, 100).
I'm first correcting your mistakes and then giving you a better alternative solution.
The member of your class and the setter function's parameter are only a single char. Change them to arrays:
char EmpName[100];
and
void setEmpName(char[]);
and in the implementation, you need to copy the content of the given array to your member:
void Employee::setEmpName(char[] x) {
memcpy(EmpName, x, 100);
}
However, this is the C way to do this.
The C++ way to do this is to use std::string. For this, change the types of the member, the parameters in the setter and in the getter as well as the type in main to std::string. To read a std::string, use the free-standing overload of getline which only takes the stream and the string (but no count):
getline(cin, name);