overloading >> operator giving me run time error C++ - c++

Can anyone help me. Below is the code which I'm trying to execute. There is no compile time error but the program crashes when the control goes to string copy statement. I'm trying to fix it for almost one hour, but still not succeeded.
#include <iostream>
using namespace std;
class test
{
private:
char* name;
friend istream& operator >>(istream&, test&);
};
istream& operator >> (istream& is, test& t)
{
char c[20];
cout << "enter something";
is >> c;
strcpy(t.name, c);
return is;
}
int main()
{
test obj;
cin >> obj;
}

The name pointer is uninitialized by the time you are invoking strcpy, which gives your program undefined behavior.
To avoid this kind of problem, use std::string rather than C strings. More concretely, redefine your class this way:
#include <string> // Needed for std::string
class test
{
private:
std::string name;
friend istream& operator >>(istream&, test&);
};
To make your program compile, you could then adapt your overload of operator >> this way:
istream& operator >> (istream& is, test& t)
{
cout << "enter something";
is >> t.name;
return is;
}
Notice, however, that you should not prompt the user for information inside your extraction operator (i.e. inside the overload of operator >>). The insertion operator is only supposed to extract an object of type test from an input stream.
Thus, to provide a complete example:
#include <iostream>
#include <string>
class test
{
private:
std::string name;
friend std::istream& operator >>(std::istream&, test&);
};
std::istream& operator >> (std::istream& is, test& t)
{
is >> t.name;
return is;
}
int main()
{
test obj;
std::cout << "enter something: ";
std::cin >> obj;
}
Also avoid using directives such as:
using namespace std;
Especially if at namespace scope and especially if in a header (not your case, but still) - they tend to cause name clashes with entities that live in the std namespace.
EDIT:
Since it seems you are not allowed to use std::string, only the first sentence of the original answer remains valid - and the part about where you should be asking input from the user, perhaps.
So this is what you can write for assigning t.name a copy of the string input by the user:
t.name = strdup(c);
You will need to include the <cstring> standard header for strdup():
#include <cstring>
I would also suggest to initialize the name pointer to null in the constructor of the test class - it doesn't get initialized by the implicitly-generated default constructor:
class test
{
test() : name(nullptr) { } // Use NULL instead of nullptr in C++03
private:
char* name;
friend istream& operator >> (istream&, test&);
};
So in a complete program:
#include <iostream>
#include <cstring>
class test
{
public:
test() : name(nullptr) { }
private:
char* name;
friend std::istream& operator >>(std::istream&, test&);
};
std::istream& operator >> (std::istream& is, test& t)
{
char c[20];
is >> c;
t.name = strdup(c);
return is;
}
int main()
{
test obj;
std::cout << "enter something: ";
std::cin >> obj;
}

Related

How does cin read strings into an object of string class?

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.

error: 'VD<Class1> Class2::data' is private within this context

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();
}

Ambiguous overload for class operator>>

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;

Overloading operator for programming exercise

I'm in a programming class and need overloading explained to me. Simple question so hopefully I'll get an answer pretty quick. My understanding is that overloading an operator allows it to be used on a class. If that is true, then how would I overload >> to work with a class? I'm working on a small program to test out this idea and i'll post it here
#include <iostream>
#include <cstdlib>
#include "data.h"
using namespace std;
int main()
{
data obj;
cout << "What is the Number?" << endl;
cin >> obj;
system("pause");
return 0;
}
class data
{
public:
data operator >> (int);
private:
};
This page tells you mostly everything you need to know about operator overloading.
In short, nearly every operator in C++ can be overloaded for user-defined types. Some operators, like +, -, or >> must be defined outside of a class since they are free-standing, whereas others like copy assignment (=), must be defined within.
For your case, overloading the >> operator can be done in the following manner:
istream& operator>>(istream& in, data& d){
// Code here
return in;
}
Where it says "Code here", place the code you need to read into the data object.
For example, let us pretend that we were reading into a Point object with an x coordinate and a y coordinate. It is formatted in the stream like so: "(x,y)". The operator overload might look like this:
istream& operator>>(istream& in, Point& p){
char c;
in >> c;
if(c != '('){
in.clear(ios_base::failbit);
return in;
}
in >> p.x >> c >> p.y >> c;
return in;
}
This is just an example with minimal format checking, but hopefully it is enough to get you started.
Note that if members in your class are private, then you should friend the istream operator in the class definition:
class data{
...
public:
friend istream& operator>>(istream&, data&);
}
case1: no need to access private data
data.h.
class data {
public:
int i;
};
std::ostream& operator>> (std::istream&, data&); // better make operator >>
// a nonmember function
// if it doesn't need access
// to private data
data.cpp
#include "data.h"
std::istream& operator>> (std::istream& is, data& d) {
is>>d.i; // here we do some logic, we do what it means to do >> on
return is; // an instance of your data class and return reference to istream
}
case2: there is a need to access private data
data.h.
class data {
private:
int i;
friend std::ostream& operator>> (std::istream&, data&);
};
data.cpp
#include "data.h"
std::istream& operator>> (std::istream& is, data& d) {
is>>d.i; // here we do some logic, we do what it means to do >> on
return is; // an instance of your data class and return reference to istream
}
If you want to bolster your understanding of what operator overloading is, consider that essentially all operators on objects (such as "+", "++", "==", "!=", etc) are member functions.
Challenge yourself to recognize Obj a, b; a = b; as Obj a; Obj b; a.operator=(b);.
Overloading is purely providing a non-default implementation.
Here is a [terrible] overload of the cast-to-const-char* operator:
class BadWolf {
const char* m_text;
public:
BadWolf(const char* text) : m_text(text) {}
// if you really want the original text and ask for it with this function...
const char* tardisTranslation() const { return m_text; }
// but if you try to use me as a const char*...
operator const char* () const { return "bad wolf"; }
};
int main(int argc, const char* argv[]) {
BadWolf message("hello, sweetie");
std::cout << "Message reads: " << (const char*)message << std::endl;
std::cout << "Tardis translation: " << message.tardisTranslaction() << std::endl;
return 0;
}
I think this is what you want.
class data
{
friend istream& operator>>( istream&, data& );
private:
int data;
};
istream& operator>>( istream& in, data& d )
{
return in >> d.data;
}

passing a stringstream to istream using operator >>

I am trying to pass a stringstream into an object(class) that has an overloaded extraction operator >> that is declared and defined. For example, the declaration for the overloaded extraction operator in object1 is
friend istream& operator >>(istream& in, Object1& input);
In object2, my declaration is almost the same
friend istream& operator >>(istream& in, Object2& input);
During the object1 extraction function, the func. gets a line, turns it into a stringstream and tries to use the extraction(>>) operator of Object2.
istream& operator >>(istream& in, Object1& input){
Object2 secondObj;
string data;
string token;
in>>data;
in.ignore();
token = GetToken(data, ' ', someint); //This is designed to take a part of data
stringstream ss(token); // I copied token into ss
ss >> secondObj; // This is where I run into problems.
}
I get the error No match for operator >>. is this because I need to convert stringstream to istream? If so, how would I do that?
The minimal program would look like this:
in main.cpp:
#include "Object1.h"
#include "Object2.h"
#include "dataClass.h"
using namespace std;
int main(){
Object1<dataClass> firstObj;
cin>>firstObj;
cout<<firstObj<<endl;
}
in Object1.h:
#ifdef OBJECT1_H_
#define OBJECT1_H_
#include <iostream>
#include <string>
#include <cstddef>
#include "Object2.h"
template<class T>
class Object1{
public:
//Assume I made the Big 3
template<class U>friend istream& operator >>(istream& in, Object1<U>& input);
template<class U>friend ostream& operator <<(ostream& out, const Object1<U>& output);
private:
Object2<T>* head;
};
template<class T>
istream& operator >>(istream& in, Object1<T>& input){
Object2 secondObj;
string data;
string token;
in>>data;
in.ignore();
token = GetToken(data, ' ', someint); //This is designed to take a part of data
stringstream ss(token); // I copied token into ss
ss >> secondObj; // This is where I run into problems.
}
template<class T>
ostream& operator <<(ostream out, const Object1<T>& output){
Object2<T>* ptr;
while(GetNextPtr(ptr) != NULL){
cout<<ptr;
ptr = GetNextPtr(ptr); //Assume that I have this function in Object2.h
}
}
The Object2.h file looks similar to Object1.h except:
template<class T>
class Object2{
public:
//similar istream and ostream funcions of Object1
//a GetNextPtr function
private:
T data;
Object2<T>* next;
};
template<class T>
istream& operator >>(istream& in, Object2<T>& input){
in>>data; //data is the private member variable in Object2.
//it is of a templated class type.
}
The following compiles fine:
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
struct X{};
struct Y{};
istream& operator>>(istream&, X&) {}
istream& operator>>(istream&, Y&)
{
stringstream ss("foo");
X x;
ss >> x;
}
int main()
{
Y y;
cin >> y;
}
Your problem must be elsewhere
Can you post a complete minimal self-contained program demonstrating the problem? Or just your declaration and definition of the function istream& operator >>(istream& in, Object2& input) ? Is it declared ahead of the Object1 version in the translation unit?