Why string is not printed?C++ - c++

#include <iostream>
using namespace std;
template<class T>
class Array{
public:
T U[10];
friend void DataOut(Array<string>);
friend void GetData(Array<string>);
};
void DataOut(Array<string> Array1){
cout << Array1.U[0];
}
void GetData(Array<string> Array1){
cin >> Array1.U[0];
cin.clear();
}
int main(){
Array<string> Arr1;
GetData(Arr1);
DataOut(Arr1);
}
I made a class template and created two functions: GetData for entering string and DataOut for printing that string, but after entering string it doesn't print it. What have I done wrong?

I placed comments where I made changes. The main fix is to pass your object by reference, especially to Getdata(). You passed a copy, put data into the copy, and when the function ended, the copy goes away and your original object was never touched.
#include <iostream>
using namespace std;
template <class T>
class Array {
public:
T U[10];
friend void DataOut(
const Array<string>&); // CHANGED: Need to take object by reference
friend void GetData(Array<string>&); // SAME
};
void DataOut(const Array<string>& Array1) { // SAME
cout << Array1.U[0];
}
void Getdata(Array<string>& Array1) { // SAME
cin >> Array1.U[0];
// cin.clear(); // CHANGED: Why?
}
int main() {
Array<string> Arr1;
Getdata(Arr1);
DataOut(Arr1);
}

Related

bind class member funtion to std::function not need check parameters?

why gcc 9.4 not check parameters when bind a class member funtion to a std::function viriable, but check when bind a global function? here is example code, CreateRpcFun has a parameter, but Test member function print doesn't have any other parameters except this, bind print to CreateRpcFun works well, but global funtion print2 cannot, can anybody explain why?
#include <functional>
#include <iostream>
#include <string>
using namespace std;
using CreateRpcFun = std::function<void(const string &)>;
class Test {
public:
Test() : str_("nihao!") {}
// bind print to CreateRpcFun passed compile
void print() { cout << str_ << endl; }
private:
string str_;
};
class Holder {
public:
CreateRpcFun CreateRpc;
};
class Other {
public:
Other(Holder h, string str) : h_(h), str_(str) {}
void run() { h_.CreateRpc("world!"); }
private:
Holder h_;
string str_;
};
void print1(const string &str) { cout << str << endl; }
void print2() { cout << "magic" << endl; }
int main() {
Test t;
Holder h;
h.CreateRpc = std::bind(&Test::print, &t);
Other o(h, "hhhh");
o.run();
h.CreateRpc = &print1;
h.CreateRpc("test");
// h.CreateRpc = &print2; // compile error
// h.CreateRpc("test");
}

Structure Arrays & Pointers

I have to use a struct array called Robot_parts[] for each part_rect struct (part_num, part_name, part_quantity, part_cost)
And through the void display function, I have to display Robot_parts[] array entirely through pointer but I don't know how, and I don't know where to declare Robot_parts[] and whether i have to put any number value inside the brackets.
So far I have:
#include <iostream>
#include <string>
using namespace std;
void display();
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
int main()
{
part_rec Robot_parts[ ] = {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
return 0;
}
void display()
{
cout<<Robot_parts[]<<endl<<endl;
}
If I also made a few other errors, please let me know. Thanks!
As stated in a comment it would be much better to use a c++ container like a std::vector or std::array.
But since your professor requires an old-style array, you could try like the code below - see the comments for explanation:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
// You have to pass a pointer (to the array) and the size of the array
// to the display function
void display(part_rec* Robot_parts, int n);
// Make a function so that you can "cout" your class directly using <<
// Note: Thanks to #BaumMitAugen who provided this comment and link:
// It makes use of the so called Operator Overloading - see:
// https://stackoverflow.com/questions/4421706/operator-overloading
// The link is also below the code section
std::ostream &operator<<(std::ostream &os, part_rec const &m)
{
// Note - Only two members printed here - just add the rest your self
return os << m.part_num << " " << m.part_name;
}
int main()
{
part_rec Robot_parts[] {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
display(Robot_parts, 3);
return 0;
}
void display(part_rec* Robot_parts, int n)
{
// Loop over all instances of your class in the array
for (int i = 0; i < n; ++i)
{
// Print your class
cout << Robot_parts[i] << endl;
}
}
The link recommended by #BaumMitAugen:
Operator overloading

Instance of class only allows 1 method, or program crashes

I am learning classes and OOP, so I was doing some practice programs, when I came across the weirdest bug ever while programming.
So, I have the following files, beginning by my class "pessoa", located in pessoa.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class pessoa {
public:
//constructor (nome do aluno, data de nascimento)
pessoa(string newname="asffaf", unsigned int newdate=1996): name(newname), DataN(newdate){};
void SetName(string a); //set name
void SetBornDate(unsigned int ); //nascimento
string GetName(); //get name
unsigned int GetBornDate();
virtual void Print(){}; // print
private:
string name; //nome
unsigned int DataN; //data de nascimento
};
Whose functions are defined in pessoa.cpp
#include "pessoa.h"
string pessoa::GetName ()
{
return name;
}
void pessoa::SetName(string a)
{
name = a;
}
unsigned int pessoa::GetBornDate()
{
return DataN;
}
void pessoa::SetBornDate(unsigned int n)
{
DataN=n;
}
A function, DoArray, declared in DoArray.h, and defined in the file DoArray.cpp:
pessoa** DoArray(int n)
{
pessoa* p= new pessoa[n];
pessoa** pointer= &p;
return pointer;
}
And the main file:
#include <string>
#include <iostream>
#include "pessoa.h"
#include "DoArray.h"
#include <cstdio>
using namespace std;
int main()
{
//pessoa P[10];
//cout << P[5].GetBornDate();
pessoa** a=DoArray(5);
cerr << endl << a[0][3].GetBornDate() << endl;
cerr << endl << a[0][3].GetName() << endl;
return 0;
}
The weird find is, if I comment one of the methods above, "GetBornDate" or GetName, and run, the non-commented method will run fine and as supposed. However, if both are not commented, then the first will run and the program will crash before the 2nd method.
Sorry for the long post.
Let's look into this function:
int *get()
{
int i = 0;
return &i;
}
what is the problem with it? It is returning pointer to a local variable, which does not exist anymore when function get() terminates ie it returns dangling pointer. Now your code:
pessoa** DoArray(int n)
{
pessoa* p= new pessoa[n];
return &p;
}
do you see the problem?
To clarify even more:
typedef pessoa * pessoa_ptr;
pessoa_ptr* DoArray(int n)
{
pessoa_ptr p= whatever;
return &p;
}
you need to understand that whatever you assign to p does not change lifetime of p itself. Pointer is the same variable as others.

I am stuck with creating an output member function

I am stuck on the output member function of the class. I have no idea how to create it and just simply couting it does not seem to work. also any other advice would be great. thanks in advance
here's the code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class StringSet
{
public:
StringSet(vector<string> str);
void add(string s);
void remove(int i);
void clear();
int length();
void output(ostream& outs);
private:
vector<string> strarr;
};
StringSet::StringSet(vector<string> str)
{
for(int k =0;k<str.size();k++)
{
strarr.push_back(str[k]);
}
}
void StringSet::add(string s)
{
strarr.push_back(s);
}
void StringSet::remove(int i)
{
strarr.erase (strarr.begin()+(i-1));
}
void StringSet::clear()
{
strarr.erase(strarr.begin(),strarr.end());
}
int StringSet::length()
{
return strarr.size();
}
void StringSet::output()
{
}
int main()
{
vector<string> vstr;
string s;
for(int i=0;i<10;i++)
{
cout<<"enter a string: ";
cin>>s;
vstr.push_back(s);
}
StringSet* strset=new StringSet(vstr);
strset.length();
strset.add("hello");
strset.remove(3);
strset.empty();
return 0;
}
Ok, you should begin by solving some errors in your code:
You use a pointer to StringSet and after that you are trying to access the member-functions with the . operator instead of the ->. Anyway, do you really need to allocated your object dynamically ?
StringSet strset(vstr); // No need to allocated dynamically your object
After that, you are calling an empty() method which does not exist...
Also if you stay on dynamic allocation, don't forget to deallocated your memory :
StringSet* strset = new StringSet(vstr);
// ...
delete strset; // <- Important
Finally, I think that your function output should write in the stream the content of your vector, you can do it that way :
#include <algorithm> // For std::copy
#include <iterator> // std::ostream_iterator
void StringSet::output( ostream& outs )
// ^^^^^^^^^^^^^ don't forget the arguments during the definition
{
std::copy(strarr.begin(), strarr.end(), std::ostream_iterator<string>(outs, "\n"));
}
HERE is a live example of your code fixed.
I would suggest you to understan how class works : http://www.cplusplus.com/doc/tutorial/classes/
If your output function is going to print the state of the StringSet object, you may implement is like this:
#include<iterator> //std::ostream_iterator
#include<algorithm> //std::copy
void StringSet::output(ostream& outs)
{
std::copy(starr.begin(), starr.end(), std::ostream_iterator<string>(outs, "\n"));
}

What am I doing wrong with my bind function here?

I wrote my bind function which returns a nullary functor because I don't have boost. Though this code compiles fine, it does not behave as I expected. When I input 2 as the number of numbers and try to enter them, the program terminates the first time I hit return. And, when I debug, it segfaults inside mem_fun_t::operator(). What am I doing wrong here? And how to rectify it?
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;
namespace MT
{
template<class Operation>
struct binder
{
protected:
Operation _op;
typename Operation::argument_type _arg;
public:
binder(Operation& fn, typename Operation::argument_type arg)
:_op(fn), _arg(arg)
{
}
typename Operation::result_type operator()()
{
return _op(_arg);
}
};
template<class Operation, class Arg>
binder<Operation> bind(Operation op, Arg arg)
{
return binder<Operation>(op, arg);
}
};
int main()
{
vector<int> vNumbers;
vector<char> vOperators;
int iNumCount = 0;
int iNumOperators = 0;
cout << "Enter number of number(s) :) :\n";
cin >> iNumCount;
int iNumber;
cout << "Enter the " << iNumCount << " number(s):\n";
generate_n(back_inserter(vNumbers), iNumCount, MT::bind(mem_fun(&istream::get), &cin));
system("clear");
copy(vNumbers.begin(), vNumbers.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
istream::get is not the right method to use, as it reads characters, not ints. You'd need to use operator>> (and selecting the right overload is very verbose), or just write a different functor:
template<class T>
struct Extract {
istream &stream;
Extract(istream &stream) : stream (stream) {}
T operator()() {
T x;
if (!(stream >> x)) {
// handle failure as required, possibly throw an exception
}
return x;
}
};
// ...
generate_n(back_inserter(vNumbers), iNumCount, Extract<int>(cin));