#include<iostream>
using namespace std;
class student
{
private:
int admno;
char sname[20];
float eng,math,science;
float total;
float ctotal()
{
return eng+math+science;
}
public:
void Takedata()
{
cout<<"Enter admission number ";
cin>> admno;
cout<<"Enter student name " ;
gets(sname);// here its giving the error
cout<< "Enter marks in english, math, science ";
cin>>eng>>math>>science;
total=ctotal();
};
void Showdata()
{
cout<<"Admission number "<<admno<<"\nStudent name "<<sname<<"\nEnglish "
<<eng<<"\nMath "<<math<<"\nScience "<<science<<"\nTotal "<<total;
}
};
int main ()
{
student obj ;
obj.Takedata();
obj.Showdata();
return 0;
}
use std::cin.getline instead of gets and std::string instead of char [].
As comments pointed out, gets is not declared in iostream. Furthermore, it has been deprecated in C++11 and removed in C++14, which means even if you include cstdio or stdio.h, it just do not compile in compilers supporting C++14.
But still, never use std::cin for char []. The reason is the same as gets. Both will make your program under the danger of buffer overflow when your input is longer than buffer, which will cause your program has unexpected behaviour, like crash. And crackers may even hack your whole computer with it.
Related
I am trying to pass the pointer to a data structure member into a function. I am passing 4 variable and the two string members are being passed but the two double members keep giving the this error. I don''t understand why this is causing an error.
The prototype:
void InputEmployeeData(std::string *LastName, std::string *FirstName, double *HrsWrkd, double *PayRate);
My Main function:
int main()
{
EmployeeRecord *ptr, Employees;
ptr = &Employees;
InputEmployeeData(ptr->LastName, ptr->FirstName, ptr->HrsWrkd, ptr->PayRate);
}
The function:
void InputEmployeeData(std::string *LastName, std::string *FirstName, double *HrsWrkd, double *PayRate)
{
/*Input module that requests employee's first name, last name, hours worked, and pay*/
std::cout << "Enter employee's first name: ";
std::cin >> *FirstName;
std::cout << "Enter employee's last name: ";
std::cin >> *LastName;
std::cout << "Enter number of hours worked: ";
std::cin >> *HrsWrkd;
std::cout << "Enter hourly pay rate: ";
std::cin >> *PayRate;
}
The definition of EmployeeRecord is missing, but according to your code, it appear that it would be expected to be something like:
class EmployeeRecord {
...
public:
string *LastName; // all pointers ?
string *FirstName;
double *HrsWrkd;
double *PayRate;
...
};
But this would require some manual memory management to create member objects using new, before storing some values. Is it really like this ?
Certainly not completely. Because according to the error message -- and assuming that there's really no problem with the string* parameters -- you seem to have:
class EmployeeRecord {
...
public:
string *LastName;
string *FirstName;
double HrsWrkd; // no pointers, but values
double PayRate;
...
};
In this case you should change your call to:
// note the use of & to get the pointer to the object
InputEmployeeData(ptr->LastName, ptr->FirstName, &ptr->HrsWrkd, &ptr->PayRate);
Now this being said, I'd recommend in this case to also change the string* to string to avoid unnecessary manual memory management. You should really need no pointer in this kind of class. In this case, you'll have to use & for all the parameters.
Even better: not only get rid of the pointers in EmployeeRecord, but consider passing the arguments by reference:
void InputEmployeeData(std::string& LastName, std::string& FirstName, double& HrsWrkd, double& PayRate)
{
...
std::cin >> FirstName; // no use of pointer dereferencing * anymore
// the reference will make sure the original object
// passed by reference will be modified
...
}
The error from the compiler is very clear. When the type of argument is double*, you must not use a double object in a call to the function.
You can change the call to the function
InputEmployeeData(&(ptr->LastName), &(ptr->FirstName), &(ptr->HrsWrkd), &(ptr->PayRate));
to remove the compiler errors.
However, it is better to change strategy algother.
Define an overload of operator>> function to read the data of an object from a stream. This is more idiomatic.
Remove the prompts from the function. Provide any prompting information before calling the operator>> function.
Use the following call to read the data, which is, to repeat myself, more idiomatic.
EmployeeRecord employee;
cin >> employee;
class EmployeeRecord
{
...
friend std::istream operator>>(std::istream& in, EmployeeRecord& emp)
{
return (in >> emp.FirstName >> emp.LastName >> emp.HrsWrkd >> em.PayRate);
}
};
int main()
{
EmployeeRecord employee;
std::cout << "Enter employee's first name, last name, hours workd, and pay rate.\n";
std::cin >> employee;
}
So i need to get code of the structure#1 (e[0]) but i get the following error;
"error: request for member 'get_code' in 'emp1', which is of pointer type 'Employee*' (maybe you meant to use '->' ?)"
i don't really understand how to fix this. Plus, it's an assigment so i'm bound to use structures,and also, i don't know what "->" is, but if it's any operator or something, im not allowed to use it cause we haven't been taught that yet.
(Answers to the similar question suggest using -> so that doesnt work for me.)
i also tried using *(emp1).get_code()
#include <iostream>
#include <string.h>
using namespace std;
struct Employee{
private:
string code;
string name;
float salary;
public:
void set_code(string c){
code=c;
}
void set_name(string n){
name=n;
}
void set_sal(float s){
salary=s;
}
string get_code(){
return code;
}
string get_name(){
return name;
}
float get_sal(){
return salary;
}
};
int main(void) {
Employee e[2],*emp1,*emp2;
string c,n;
float s;
for (int i=0;i<2;i++){
cout<<"Enter code for employee "<<i+1;
cin>>c;
e[i].set_code(c);
cout<<"Enter name for employee "<<i+1;
cin>>n;
e[i].set_name(n);
cout<<"Enter salary for employee "<<i+1;
cin>>s;
e[i].set_sal(s);
}
*emp1=e[0];
cout<<emp1.get_code();
}
First of all, this line is not correct:
*emp1=e[0];
What your line does is assign the structure value 'e[0]' to the structure at pointer 'emp1'. However, the pointer 'emp1' is never initialized, so you'd end up writing in an invalid location.
What you need to write is:
emp1=&e[0];
That will actually set emp1 to the location of 'e[0]'.
Secondly, the symbol '->' is what you use when you want to access a member of a pointer.
In this case you should not write:
cout<<emp1.get_code();
But rather:
cout<<emp1->get_code();
The reason why you need to write that is that 'emp1' is a pointer. Thus, to access its member 'get_code', you need to use the symbol '->'.
when i compile the program i get an error about int when i create a bookClass object using the 2 argument constructor. the error has somerthing to do with the integer argument parsed to the constructor. the program is:
#include <iostream>
#include <string>
using namespace std;
class bookClass{
private:
string bookName;
int bookNumber;
public:
void setName(string c){
bookName=c;
}
void setNumber(int d){
bookNumber=d;
}
string getName(){
return bookName;
}
int getNumber(){
return bookNumber;
}
bookClass(string a, int b){
bookName=a;
bookNumber=b;
}
};
int main()
{
int numberr;
string name;
cout << "Enter the book name: ";
cin >> name;
cout << "\nEnter the book number: ";
cin >> numberr;
bookClass book=new bookClass(name, numberr);
cout << "\n\nThe book " << book.getName() << " has book number " <<
book.getNumber() << endl;
return 0;
}
Compiling your code I didn't get the error you suggested. However, there is an issue with this line:
bookClass book = new bookClass(name, numberr);
C++ is not Java. new returns a pointer to memory dynamically allocated for the given class.
What you want is just:
bookClass book (name, numberr);
The problem with your code is simple. I suppose you were programming in Java or C# before C++. In C++ we call new operator only if we want to create an object explicitely on heap (and get a pointer to it).
bookClass* book=new bookClass(name, numberr);
However, now you are in troubles because you are calling book.getName() where book is of type pointer to something and it has no member getName(). You have to first dereference that pointer and then call a member function (*book).getName(); or simply book->getName();.
However, since C++'s objects do not have to be on the heap (Java objects have to) you can create an object without new operator using bookClass book(name, numberr);
I have basic file handling code of reading file named"student.dat" using visual studio.
the output reads the file and displays the result in console but visual studio pops up the dialog as
code:
#include<iostream>
#include<fstream>
#include<conio.h>
#include<string>
using namespace std;
class student
{
int admno;
// char name[20];
string name;
public:
void getdata()
{
cout<<"\n\nEnter The Name of The Student ";
//gets(name);
cin>>name;
getch();
cout<<"\nEnter The admission no. ";
cin>>admno;
// getch();
}
void showdata()
{
cout<<"\nAdmission no. : "<<admno;
cout<<"\nStudent Name : ";
cout<<name;
//puts(name);
}
int retadmno()
{
return admno;
}
};
int main()
{
student obj;
ifstream fp1;
fp1.open("student.dat",ios::binary);
while(fp1.read((char*)&obj,sizeof(obj)))
{
obj.showdata();
}
fp1.close();
return 0;
}
You are allowed to load raw data only to some POD objects. This line is an error:
fp1.read( (char*)&obj,sizeof(obj) );
because student contains std::string. std::string contains a pointer to a memory block which becomes invalid and totally useless after the object is destroyed. It means the data you load to std::string is just a garbage.
I'd think about object serialization. Boost serialization is a good way to start.
You try to store/load an object to a file, which is invalid.
while(fp1.read((char*)&obj,sizeof(obj)))
Objects may contain references to memory (std::string e.g.) that are invalid after loading. You have to provide serialization for your objects or use plain structs without pointers or references to store your data. E.g.:
struct {
int admno;
char[20] name;
}
If you need strings with variable length, you may use a string store:
struct {
int admno;
size_t name_index;
}
std::vector<std::string> names;
To store, iterate over your names and save length and .c_str of each std::string. To read, do it the other way around and read length into n, read n bytes into a buffer and construct a std::string out of the buffer.
You might have a look at http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html
You never call GetData so admno is not instantiated in ShowData
This is my code to receive string.
But I don't know what causes a problem.
Anybody knows?
#include<iostream>
#include<cstring>
using namespace std;
class person{
private:
char name[100];
//char * name;
public:
person(void) : name(){}
person(person& myPerson);
~person(void) {delete []name;}
void read();
void write();
};
person::person(person& myPerson ){
strcpy(name ,myPerson.name);
}
void person::read(){
cout<< "read name from console: " ;
cin >> name;
}
//////// <<---- problem point.
void person::write(){
cout << name << endl;
}
void main(void) {
person p1;
p1.read();
//p1.write();
getchar();
}
//I insert "getchar()" to remain console window for a while
Remove delete []name; from the destructor of person. You should only free memory that is heap allocated, with malloc() or new, and not space that is stack allocated, like your fixed-size array declared char name[100]. This change will fix the memory error you receive when the destructor is executed as the program exits.
Your code has a number of errors or bad style.
First, it's recommend to use C++ standard library facilities as much as possible. So use std::string instead of char[SIZE].
Second, use int main{return 0;} instead of void main{}.
Third, delete [] name; will lead to a memory error. You are freeing stack memory not heap memory.
Last, in my opinion, class names should start with a capital letter (Person).