So, the problem is several errors at compile time.
ReadMovieData(string* title, string* director) cannot convert from movieInfo to string*
DisplayMovieData(string title, string director) cannot convert from movieInfo to string
No operator found which takes a right-hand operand of type 'movieInfo' (or there is no acceptable conversion.
The bottom error happens twice in DisplayMovieData() so I wrote it once for simplicity sake.
The ReadMovieData function should accept a structure pointer reference variable and the DisplayMovieData function should accept a MovieInfo structure variable.
The main function creates an array of 2 MovieInfo struct variables and the other functions should be called on an element of the array.
The code I have finished is below.
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
//prototypes
int ReadMovieData(string* title, string* director);
int DisplayMovieData(string title, string director);
struct movieInfo {
string title, director;
};
int main(){
const int SIZE = 2;
movieInfo movieList[SIZE];
movieInfo movie;
//supposed to assign data to movieList[i] at some point
for (int i = 0; i < SIZE; i++){
ReadMovieData(movie, movie);
DisplayMovieData(movie, movie);
}
return 0;
}
int ReadMovieData(movieInfo &title, movieInfo &director){
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return 0;
}
int DisplayMovieData(movieInfo title, movieInfo director){
cout << "The movie name is: " << title << endl;
cout << "The director of " << title << " is: " << director << endl;
return 0;
}
There are mismatches between your function prototypes and their definitions, as you can see comparing the parameter types in both.
Note that since you defined a structure for the movie info, you can directly pass it to the reading and displaying functions (instead of passing the single structure data member strings).
You may want to read the following compilable code:
#include <iostream>
#include <string>
using namespace std;
struct MovieInfo {
string title;
string director;
};
void ReadMovieData(MovieInfo& movie);
void DisplayMovieData(const MovieInfo& movie);
int main() {
const int SIZE = 2;
MovieInfo movieList[SIZE];
for (int i = 0; i < SIZE; i++) {
ReadMovieData(movieList[i]);
DisplayMovieData(movieList[i]);
}
}
// Since movie is an output parameter in this case, pass by non-const reference.
void ReadMovieData(MovieInfo& movie) {
//get the movie name
cout << "What is the movie? ";
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin >> movie.director;
}
// Since movie is an input parameter in this case, pass by reference to const.
void DisplayMovieData(const MovieInfo& movie) {
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title
<< " is: " << movie.director << endl;
}
The errors are pretty explanatory and clear - your function takes string* but you're passing movieInfo - unrelated types can't just magicaly convert one to another.
What you probably want is pass the data members of movieInfo:
ReadMovieData(&movie.title, &movie.director);
It would be better if arguments were not pointers - use references instead. Where you won't be changing the arguments, the references should be to const type.
Even better, why not just pass moveInfo
ReadMovieData(movieInfo& movie);
and let the function deal with the internals of the class? This better encapsulates data and doesn't lead to spaghetti code quite so fast.
Also, the declarations and definitions need to match (otherwise you'd be overloading) - you're using pointers in some places and references/values in others.
Finally, here's how an overload of operator<< might look like:
std::ostream& operator<<(std::ostream& os, const movieInfo& m)
{
return os << "Title: " << m.title << ", Director: " << m.director;
}
Your class movieInfo does not have an overloaded << operator, which is necessary is you want to work with iostream, however, you can pass the strings contained in movieInfo:
int DisplayMovieData(string &title, string &director) { }
Call like:
DisplayMovieData(movie.title, movie.director);
You are declaring the function with this signature
int ReadMovieData(string* title, string* director);
but you're defining it using
int ReadMovieData(movieInfo &title, movieInfo &director) {
// ...
}
These don't match!
The code is totally invalid. I suppose the valid code should look the following way
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
struct movieInfo
{
string title, director;
};
//prototypes
movieInfo ReadMovieData();
void DisplayMovieData( const movieInfo & );
int main()
{
const int SIZE = 2;
movieInfo movieList[SIZE];
//supposed to assign data to movieList[i] at some point
for ( int i = 0; i < SIZE; i++ )
{
movieList[i] = ReadMovieData();
DisplayMovieData( movieList[i] );
}
return 0;
}
movieInfo ReadMovieData()
{
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return movie;
}
void DisplayMovieData( const movieInfo &movie )
{
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title << " is: " << movie.director << endl;
}
Related
This is my first problem to ask about, please scrutinize me if necessary :)
I'm trying to solve a problem for a C++ class at school. I have encountered an error I really can't grasp. I'm in taking my baby steps in programming.
The assignment says:
two classes,
inheritance mechanism used,
database holding students using dynamic memory allocation,
a way of enlarging the database without using advanced data structures,
overload stream operators for objects of created class.
This is my code:
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
protected:
char Name[20];
string Surname;
int Age;
public:
virtual void whoAmI()=0;
friend ostream &operator<< (ostream &out_, Person &s); // stream overl.
friend istream &operator>> (istream &in_, Person &s);
friend void resizeArr(Person* oldList, int oldSize, int newSize); // array enlarge
};
class Student :public Person
{
public:
Student(){}
Student(char name[], string surname, int age )
{
strcpy(Name, name);
Surname = surname;
Age = age;
}
virtual void whoAmI() // basically replaced by overloaded ostream
{
//cout << "I am a student\nMy name is " << name <<" "<< surname << "; I'm "<< age << " years old.";
cout << Name << endl;
cout << Surname << endl;
cout << Age << endl;
}
};
istream &operator>> (istream &in_, Person &s) // through reference: stream object and overloading object
{
cout << "New student record: "<< endl;
cout << "Name: " << endl;
in_ >> s.Name;
cout << "Surname: " << endl;
in_ >> s.Surname;
cout << "Age: " << endl;
in_ >> s.Age;
cout << endl;
return in_;
}
ostream &operator<< (ostream &out_, Person &s)
{
out_ << "Name:\t\t" << s.Name << endl << "Surname:\t" << s.Surname << endl <<"Age:\t\t" << s.Age << endl;
return out_;
}
void resizeArr(Student* oldList, int oldSize, int newSize)
{
Student *newList = new Student[newSize];
for(int i = 0; i < oldSize; i++) // COPYING
{
newList[i]=oldList[i];
}
for(int i = oldSize ; i < newSize ; i++) // init rest as blank students to avoid errors
{
newList[i] = Student( "undef" , "undef", 0);
}
delete [] oldList; // free memory used for old array
oldList = newList; // reset pointer to new array
}
int main()
{
int initSize = 2;
int plusSize = 4;
Student *list1 = new Student[initSize];
for (int i=0; i<initSize; i++){ // initialize each cell as a blank student
list1[i] = Student( "undef" , "undef", 0);
}
for (int i=0; i<initSize; i++) // display initial array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
resizeArr(list1, initSize, plusSize); // FUNCTION CALL
cout << endl << "\tEnlarger database: " << endl << endl; // for the sake of console output clarity
for (int i=0; i<plusSize; i++) // display enlarged array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
getch();
return 0;
}
I have previously prototyped such a mechanism using integer arrays and it worked... now I'm getting a crash for an unknown reason.
Please point me in the right direction.
Edit:
The program compiles and runs, the new array seems to hold the first two elements of the old array, and by the point it reaches the first new element, the program crashes (the memory cell seems to be trolling me and holds a smiley face).
The first two Student objects are copied, the third element causes an error:
The issue lies in the definition of your resize function:
void resizeArr(Student* oldList, int oldSize, int newSize)
Unless otherwise noted, all parameters passed to a function are by value. Even though the first parameter is a pointer, that only allows to modify the memory to which it is pointing, not the pointer itself.
You need to change the declaration of the first parameter to either Student **, with code changed in the method to handle the double dereference, or change it to Student*&.
I suspect that you were lucky that it worked for integer.
You are passing a pointer to a student list to your resizeArr routine, i.e. void resizeArr(Student* oldList, int oldSize, int newSize), but not a pointer to a pointer.
Hence, assigning a new/different memory block to the pointer within resizeArr will let the variable within resizeArr point to the new address, but the pointer that has been passed to resizeArr (i.e list1) is not changed.
I'd suggest to change the logic to Student* resizeArr(Student* oldList, int oldSize, int newSize) and call it like list1 = resizeArr(list1, initSize, plusSize);
This is analogous to the signature of void* realloc (void* ptr, size_t size);.
This coding where I used function overloading is a code where user have to input their pointer for 4 subjects and its credit hour so it prints out their GPA. The thing is I have 3 parameter in Student(string test123, string nama, string vinto ). But I only want to display either one of the string. Lets say I want the Vinto to be print out. How can I call the vinto in my Display function so that it prints out Vinto. Heres's My coding.
CPP.cpp
#include <iostream>
#include "student.h"
using namespace std;
void main(void)
{
string nama;
string test123;
int i;
Student StudentA(test123, nama, "vinto");
cout << "key in points for 4 subject\n";
StudentA.Getpointers();
StudentA.Display(test123);
}
Student.h
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
Student(string test123, string nama, string vinto );
void Getpointers();
void Display(string name);
private:
double points[4];
int creditHours[4];
string name;
double CalculateGPA();
};
Student.cpp
#include <iostream>
#include <iomanip>
#include<string>
#include "student.h"
using namespace std;
Student::Student(string test123, string nama, string vinto)
{
name = nama;
}
void Student::Getpointers()
{
for (int i = 0; i<4; i++)
{
cout << "points for subject :" << i + 1 << endl;
cin >> points[i];
cout << "credit hour for subject " << i + 1 << endl;
cin >> creditHours[i];
}
}
void Student::Display(string name)
{
cout << "Hello " << name << endl;
cout << "Your current GPA is " << setprecision(3) << CalculateGPA() << endl;
}
double Student::CalculateGPA()
{
double totalpoints = 0;
int totalcreditHours = 0;
for (int i = 0; i<4; i++)
{
totalpoints += (points[i] * creditHours[i]);
totalcreditHours += creditHours[i];
}
return totalpoints / totalcreditHours;
}
Well, the vinto argument of your constructor is not saved anywhere, so in this example you cannot get it back. However, you could store it:
First, add a vinto field to the class:
class Student
{
public:
Student(string test123, string nama, string vinto );
void Getpointers();
void Display(string name);
private:
double points[4];
int creditHours[4];
string name;
string vinto;
double CalculateGPA();
};
Then, store the vinto argument value in this field:
Student::Student(string test123, string nama, string vinto)
{
name = nama;
this->vinto = vinto;
}
After this, you may use vinto:
void Student::Display(string name)
{
cout << "Hello " << name << endl;
cout << "Your current GPA is " << setprecision(3) << CalculateGPA() << endl;
cout << "Your vinto is " << vinto << endl;
}
Also, it's a bit strange that you store student's name in the object field, but use another name (which is passed to Student::Display) to say Hello to him.
I am trying this piece of code in vs 2008
#include <stdio.h>
#include <iostream>
#include <string>
typedef struct _first
{
int age;
std::string name;
}first;
typedef struct _second
{
int age;
char name[20];
}second;
void copy_structure()
{
first s;
second f;
f.age = 15;
cout<<"Enter the name"<<endl;
fgets(f.name, 20, stdin);
memcpy(&s,&f,20);
cout << "Name: " << s.name << endl;
cout << "Age: "<< s.age << endl;
}
int main()
{
copy_structure();
return 0;
}
while building I didn't get any error but when I run, name field is empty over here
cout << "Name: " << s.name << endl;
I am not getting any output over here, can somebody help me to solve this issue.
You should use an approach based on member-wise copying. For example
void copy_structure()
{
first f;
^^
second s;
^^
s.age = 15;
cout<<"Enter the name"<<endl;
fgets(s.name, 20, stdin);
f.age = s.age;
f.name = s.name;
cout << "Name: " << f.name << endl;
cout << "Age: "<< f.age << endl;
}
Otherwise the internals of the object name of the type std::string will be overwritten and the program will have undefined behaviour.
This looks like C but not like C++... Your current code will also brick your std::string instance. memcpy is dangerous and should not be used, unless you have a very, very good reason. I never had a reason for this so far.
My suggestion:
#include <iostream>
#include <string>
using namespace std;
struct second
{
int age;
char name[20];
};
struct first
{
int age;
string name;
first& operator=(const second& rhs);
};
// some operator for copying
first& first::operator=(const second& rhs)
{
age = rhs.age;
name = rhs.name;
return *this;
}
int main()
{
first s;
second f;
f.age = 15;
cout << "Enter your name" << endl;
cin >> f.name;
s = f;
cout << "Name: " << s.name << endl;
cout << "Age: " << s.age << endl;
return 0;
}
This is improvable, of course. You would usually rather use classes than structs. And you would might also have an operator>> for second.
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);
I have a question regarding a homework assignment.
I have two classes. One is called ticket.cpp, and the other is called TicketOrder.cpp
The main is within the ticket.cpp.
I am using a g++ compiler on Linux.
What I'm doing is trying to is print out a vector of a TicketOrder object called orders, but it gives me the following error:
ticket.cpp:57: error: no match for 'operator<<' in 'std::cout << orders. std::vector<_Tp, _Alloc>::operator[] with _Tp = TicketOrder, _Alloc = std::allocator'
Here is my code:
ticket.cpp
#include <iostream>
#include <vector>
#include <limits>
#include <cctype>
#include "TicketOrder.cpp"
using namespace std;
int main ()
{
int numberoftickets=0;
string input2;
char input3;
int profit=0;
vector <TicketOrder> orders;
int atotalmoney=0;
int btotalmoney=0;
int ctotalmoney=0;
int dtotalmoney=0;
int etotalmoney=0;
do
{
cout << "\nPick a ticket that you would like to buy: \n\n";
cout << "(A) Students without an activity card: $2.00 \n";
cout << "(B) Faculty and staff: $3.00 \n";
cout << "(C) USC alumni: $5.00 \n";
cout << "(D) UCLA students and alumni: $20.00 \n";
cout << "(E) Everyone else: $10.00 \n";
cin >> input3;
if (input3=='A')
{
cout << "How many tickets do you wish to buy? " <<endl;
if (numberoftickets >0)
{
TicketOrder order;
order.setQuantity(numberoftickets);
order.setType(input3);
orders.push_back(order);
for (int i=0; i< orders.size(); i++)
{
cout << orders[i];
}
}
}
else
{
cout << "Sorry did not recognize input, try again. " << endl;
}
} while (input3 != 'S');
TicketOrder.cpp:
#include <iostream>
using namespace std;
class TicketOrder
{
public :
//Getters
int getQuantity() const
{
return quantity;
}
char getType() const
{
return type;
}
//Setters
void setQuantity (int x)
{
quantity=x;
}
void setType(char y)
{
type =y;
}
private:
char type;
char quantity;
};
As the compiler is clumsily trying to explain, the code is missing an operator<< for the TicketOrder class.
class TicketOrder {
public:
friend std::ostream& operator<<(std::ostream& os, TicketOrder const& order) {
os << "Type: " << type << ", quantity: " << quantity;
return os;
}
char type;
int quantity;
};
(Note: you probably want to change quantity to int.)
You must add the operator << function as a friend to be able to print values from your TicketOrder objects with cout. Further reading
You're attempting to use the << operator on cout and a TicketOrder object. That is undefined. You should use the TicketOrder object to generate a string first, then output that via cout. Either that, or you can define the << operator for the TicketOrder class, as described in one of the other two answers.