I try to overload ostream operator in a class Student as follows:
//Student.h
class Student
{
public:
Student(){}
~Student(){}
friend std::ostream& operator<< (std::ostream&,const Student&);
friend std::istream& operator>> (std::istream&,const Student&);
private:
char* snum;
};
//Student.cpp
#include "Student.h"
std::ostream& operator<< (std::ostream& output,const Student& c)
{
output<<c.snum<<", "<<c.name<<", "<<c.email<<endl;
return output;
}
std::istream& operator>> (std::istream& input,const Student& cN)
{
cout<<"Input number: ";
input>>cN.snum;
return input;
}
//main.cpp
#include "Student.h"
int main()
{
Student st;
std::cin >> st;
std::cout << st << std::endl;
return 0;
}
But when i input the snum,i get error message "Segmentation Fault".
I change char* snum; to char snum;,it return compiler error The operation "std::istream>> const char" is illegal.
Thank you for help.
You need that snum will point on allocate memory and then you can input it with data, for exemple:
char* p_var = new char[20]; // 20 bytes allocation
// ... using p_var
delete[] p_var; // Releasep_var memory
In your case, you should do the allocation in the Ctor and the release in the Dtor.
you can read this for more info:
http://www.cplusplus.com/doc/tutorial/basic_io/
tell me if your problem got solved by using below changes...
class Student
{
private:
char snum;
char name;
char email;
public:
Student(){};
~Student(){};
friend std::ostream& operator<< (std::ostream&,Student&);
friend std::istream& operator>> (std::istream&,Student&);
};
std::ostream& operator<< (std::ostream& output,Student& c)
{
output<<c.snum<<", "<<c.name<<", "<<c.email<<endl;
return output;
}
std::istream& operator>> (std::istream& input, Student& cN)
{
cout<<"Input number: ";
input>>cN.snum;
input>>cN.name;
input>>cN.email;
return input;
}
int main()
{
Student st;
std::cin >> st;
std::cout << st << std::endl;
return 0;
}
use string or char array or assign char *x some memory before using for cin...
Related
Reading some documentation online I found that istream class was part of C++ long before the string class was added. So the istream design recognizes basic C++ types such as double and int, but it is ignorant of the string type. Therefore, there are istream class methods for processing double and int and other basic types, but there are no istream class methods for processing string objects.
My question is if there are no istream class methods for processing string objects, why this program works and how ?
#include <iostream>
int main(void)
{
std::string str;
std::cin >> str;
std::cout << str << std::endl;
return 0;
}
This is possible with the use operator overloading. As shown in the below example, you can create your own class and overload operator>> and operator<<.
#include <iostream>
class Number
{
//overload operator<< so that we can use std::cout<<
friend std::ostream& operator<<(std::ostream &os, const Number& num);
//overload operator>> so that we can use std::cin>>
friend std::istream &operator>>(std::istream &is, Number &obj);
int m_value = 0;
public:
Number(int value = 0);
};
Number::Number(int value): m_value(value)
{
}
std::ostream& operator<<(std::ostream &os, const Number& num)
{
os << num.m_value;
return os;
}
std::istream &operator>>(std::istream &is, Number &obj)
{
is >> obj.m_value;
if (is) // check that the inputs succeeded
{
;//do something
}
else
{
obj = Number(); // input failed: give the object the default state
}
return is;
}
int main()
{
Number a{ 10 };
std::cout << a << std::endl; //this will print 10
std::cin >> a; //this will take input from user
std::cout << a << std::endl; //this will print whatever number (m_value) the user entered above
return 0;
}
By overloading operator>> and operator<<, this allows us to write std::cin >> a and std::cout << a in the above program.
Similar to the Number class shown above, the std::string class also makes use of operator overloading. In particular, std::string overloads operator>> and operator<<, allowing us to write std::cin >> str and std::cout << str, as you did in your example.
Because std::string overload the >> and << operator to return the type std::istream and std::ostream
How they overload it, you can look in this link that Mat gives.
You can create your own class and overload operators, too. Here is an example:
class MyClass
{
int numberOne;
double numberTwo;
public:
friend std::ostream& operator<<(std::ostream &out, const MyClass& myClass);
friend std::istream& operator>> (std::istream& in, MyClass& myClass);
};
// Since operator<< is a friend of the MyClass class, we can access MyClass's members directly.
std::ostream& operator<<(std::ostream &out, const MyClass& myClass)
{
out << myClass.numberOne << ' ' << myClass.numberTwo;
return os;
}
// Since operator>> is a friend of the MyClass class, we can access MyClass's members directly.
std::istream& operator>> (std::istream& in, MyClass& myClass)
{
in >> myClass.numberOne;
in >> myClass.numberTwo;
return in;
}
int main()
{
MyClass myClass;
std::cin >> myClass;
std::cout << myClass;
}
Because of operator overloading.
In your case, including <iostream> will include <string>, a specialization of std::basic_string. And std::basic_string has the non-member functions operator<< and operator>> defined.
Similarly, you can also overload operator<< and operator>> for your own custom types.
So I have this code where an object of class Group has vector with objects from class Student. I am already writing information about the students from the vector into a file but I have problem with reading this information back. How can I do that?
Here is my code so far:
class Group
{
private:
string name;
vector <Student*> studentList;
public:
~Group();
Group(void);
Group(string s);
void addStudent(string name,int age,int stNum);
void removeStudent(int stNum);
friend ostream& operator << (std::ostream& out, const Group& g) {
out << g.name << "\n";
out << g.studentList.size() << "\n";
for (unsigned i=0;i<g.studentList.size();i++) {
out<< g.studentList[i]->getStudentName()<<"\n";
out<< g.studentList[i]->getStudentAge()<<"\n";
out<< g.studentList[i]->getStudentNumber()<<"\n"<<endl;
}
return out;
}
friend istream& operator>>(std::istream& in, Group& g){
in >> g.name;
for (unsigned i=0;i<g.studentList.size();i++) {
//READ DATA FROM FILE
}
return in;
}
};
Gathering up the commentary. Note this pushes the hard part, the reading and writing, into Student and I left that bit blank. Normally I'd do it because I'm evil, but apparently in this case it is already written.
Major changes:
No Student pointers. Lest memory management overhead and better cache friendliness! By Grabthar's hammer. What a savings.
Student does the Student reading and writing.
std::vector handles the element counting so it doesn't need to be stored in and read from the output. Note: This could slow the reading down a little because you can't pre-allocate storage in the vector.
#include <string>
#include <iostream>
#include <vector>
// note the lack of using namespace std;
// it can be problematic, and especially so in a header.
class Student
{
//fill in the blanks
friend std::ostream& operator <<(std::ostream& out, const Student& s)
{
//fill in the blanks
return out;
}
friend std::istream& operator >>(std::istream& in, const Student& s)
{
//fill in the blanks
return in;
}
};
class Group
{
private:
std::string name;
std::vector<Student> studentList; // death to pointers!
public:
//~Group(); // Don't need a destructor without the pointer
Group(void);
Group(std::string s);
void addStudent(std::string name, int age, int stNum);
void removeStudent(int stNum);
friend std::ostream& operator <<(std::ostream& out, const Group& g)
{
out << g.name << "\n";
//out << g.studentList.size() << "\n"; not necessary. vector handles it.
for (std::vector<Student>::const_iterator it = g.studentList.cbegin();
it != g.studentList.cend();
++it)
{
if (!(out << *it))// let Student's << do all the work
{ // write failed. Might as well stop trying to write.
break;
}
}
return out;
}
friend std::istream& operator>>(std::istream& in, Group& g)
{
in >> g.name;
Student temp;
while (in >> temp) // let Student's >> do all the work
{
g.studentList.push_back(temp);
}
return in;
}
};
I'm having some problems with my code. I declared in the .h two friend functions which are:
#ifndef CLASS2_H
#define CLASS2_H
#include "class1.h"
#include <string>
#include <iostream>
using namespace std;
class Class2{
private:
VD<Class1> data; //Vector of objects of Class1
VD<int> number; //Vector of int
public:
Constructor();
friend istream & operator >> (istream & i, const Class1 & other);
friend ostream & operator << (ostream &o, const Class1 & other);
};
#endif
And the .cpp is:
istream & operator >> (istream & i,Class2 & other){
string n;
Class1 ing;
getline(i,n);
while(!i.eof()){
i >> ing;
otro.data.Insert(ing,otro.data.size()-1);
}
return i;
}
ostream & operator << (ostream &o, const Ingredientes & otro){
for(int i = 0; i < otro.datos.size(); i++){
o << other.data[i];
}
return o;
}
So, the error that I'm getting is:
error: 'VD Class2::data' is private within this context. I declared the functions of operator >> y << friend but I doesn't make any sense that compiler says to me that I can't access to the private data. Any help please?
You seem to be very new at C++, and you seem to be doing quite complex things, while you're not understanding the basics yet. Please find a tutorial or so.
A few things:
using namespace std; is -especially in a header- never a good idea. It's like you're going on holiday, but bring along everything in your house. Refer to standard namespace functions using std::.
an istream& operator>>() cannot put anything in an object that is declared const.
using vec.insert(obj, vec.size()-1) is reinventing one of the most essential funcitons of std::vector: push_back()...
while (!i.eof()) is not good, because eof is not set until after the read past the end.
there's no string& operator>>(string& str, Class1& obj) function defined. We have std::stringstream for that.
To show how you could realize some of this, I'm going to write some example code. Please don't just copy it, but try to understand it.
test.txt
1 2 3 4
5 6 7 8
main.cpp
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
template <typename T>
using VD = std::vector<T>;
class Class1 {
private:
int d;
public:
friend std::istream& operator>> (std::istream& i, Class1& obj) {
i >> obj.d;
return i;
}
friend std::ostream& operator<< (std::ostream& o, const Class1& obj) {
o << obj.d;
return o;
}
};
class Class2 {
private:
VD<Class1> data{}; //Vector of objects of Class1
public:
void Clear() { data.clear(); }
friend std::istream& operator>> (std::istream& i, Class2& obj) {
std::string line;
std::getline(i, line);
std::istringstream iss(line);
Class1 ing;
while (iss >> ing) {
obj.data.push_back(ing);
}
return i;
}
friend std::ostream& operator<< (std::ostream& o, const Class2& obj) {
for (auto const& cl1 : obj.data) {
o << cl1 << " ";
}
return o;
}
};
int main() {
Class2 cl2;
std::ifstream ifs;
ifs.open("test.txt");
if (ifs.is_open()) {
ifs >> cl2;
}
std::cout << "first line: " << cl2 << '\n';
cl2.Clear();
if (ifs.is_open()) {
ifs >> cl2;
}
std::cout << "second line: " << cl2 << '\n';
ifs.close();
}
class student
{
private:
int RollNo;
string Name;
public:
student(){}
student(int rn, string n)
{
RollNo = rn;
Name = n;
}
~student(){}
int getRollNo() { return RollNo; }
string getName() { return Name; }
friend ifstream& operator>>(ifstream & ifs, student &s);
friend ofstream& operator<<(ofstream & ofs, student &s);
friend istream& operator>>(istream & is, student &s);
friend ostream& operator<<(ostream & os, student &s);
};
//overloading operator>> for reading from file using input
ifstream& operator>>(ifstream &ifs, student &s)
{
file stream object
ifs.read((char*) &s,sizeof(s));
return ifs;
}
//overloading operator<< for writing to file output file stream object
ofstream& operator<<(ofstream & ofs, student &s)
{
ofs.write((char*) &s,sizeof(s));
return ofs;
}
//overloading operator<< to write to output stream using its
ostream& operator<<(ostream & os, student &s)
{
object and student object
os<<"Roll No. = "<<s.RollNo<<endl;
os<<"Name = "<<s.Name<<endl;
return os;
}
//overloading operator>> to write into student object using
istream& operator>>(istream & is, student &s)
{
inputstream object
cout<<"Enter R0ll No.: ";
is>>s.RollNo;
cout<<"Enter Name: ";
is>>s.Name;
return is;
}
//main block
int main()
{
student s1(112,"abhimanyu"),s2(123,"abc");
student temp;
ofstream ofileobject("abc.txt",ios:: out | ios::trunc);
ofileobject<<s1<<s2;
ofileobject.close();
ifstream ifileobject("abc.txt",ios::in);
ifileobject>>temp;
cout<<temp;
ifileobject>>temp;
cout<<temp;
ifileobject.close();
}
i am working on a program to read and write student data to
file with insertion and extraction operators overloaded for
both istream/ostream and ifstream/ofstream but i got an
error "munmap_chunk(): invalid pointer"
i tried hard but unable to get a solution to this invalid pointer
You can't read/write non-POD objects, like std::string, from/to file using of.write((char*)&obj,sizeof(obj));
You need to properly read/write such objects by value, i.e. something like:
of.write(str.data(), str.length() + 1);
Where +1 is for writing '\0' terminator. Or just using objects overloaded << operator. I.e.:
of << str;
Edit:
So basically you file operators should look like:
ifstream& operator>>(ifstream &ifs, student &s)
{
ifs >> s.RollNo >> s.Name;
return ifs;
}
ofstream& operator<<(ofstream & ofs, student &s)
{
ofs << s.RollNo << s.Name;
return ofs;
}
I am trying to overload the class operator for istream (>>) and I am getting the error Ambiguous overload for operator>> for some reason. The operator for ostream works perfectly but istream does not.
Does someone know why?
#include <iostream>
#include <fstream>
using namespace std;
class Person
{
public:
Person(string name="Empty", int num=0)
:name(name), num(num){}
friend istream& operator>> (istream& is, Person& o)
{
is >> o.name>> o.num;
return is;
}
friend ostream& operator<< (ostream& os, Person& o)
{
return os << o.name<< " " << o.num<< endl;
}
private:
string name;
int num;
};
int main()
{
ifstream fajl("input.txt");
Person a();
fajl >> a ;
cout << a ;
}
input.txt:
Name1 15
Name2 16
I get the error in line: fajl >> a ;
This is not a variable declaration:
Person a();
is a function declaration. The correct code to declare a variable is:
Person a;