I have a problem with reading & printing my class - c++

I have a problem with printing my class. I want this class to read a binary number and then print it. I am a Beginner, so here can be a really dumb mistake.
This code has a wrong output, but a correct input.
I tried to fix this, but I couldn't. I hope you will find the mistake.
Please help. Thanks!
Here is the code:
#include <iostream>
using namespace std;
class Binary
{
int len;
bool* arr;
public:
Binary();
Binary(const Binary&);
friend istream& operator >> (istream&, Binary&);
friend ostream& operator << (ostream&, const Binary&);
};
Binary::Binary()
{
len = 0;
arr = new bool[0];
}
Binary::Binary(const Binary& b)
{
len = b.len;
arr = new bool[len];
for (int i = 0; i < len; i++) {
arr[i] = b.arr[i];
}
}
istream& operator>>(istream& in, Binary& b)
{
char line[101];
in.getline(line, 100);
b.len = strlen(line);
b.arr = new bool[b.len];
for (int i = 0; i < b.len; i++) {
b.arr[i] = (line[i] == '0' ? 0 : 1);
}
return in;
}
ostream& operator<<(ostream& out, const Binary& b)
{
for (int i = 0; i < b.len; i++) {
out << b.arr;
}
return out;
}
int main() {
Binary a;
cin >> a;
cout << a;
return 0;
}

The problem is with this line of code:
out << b.arr;
You are printing the array pointer, b.arr, instead of a value in the array.
This will work:
out << b.arr[i] ? '1' : '0';
You should also consider writing a destructor to free your previously allocated memory, and also free the previous array before overwriting it's pointer on this line:
b.arr = new bool[b.len];

Related

Why am i getting this error: could not convert '0' from 'long int' to 'Sparse'

I am creating a code for a sparse matrix, basically for adding two sparse matrices.
And now it's not working. showing some error with return NULL.
When checking for the condition that if the dimensions of the matrix are not the same, it will not execute the program as the condition will be false and it will return NULL but it's showing an error there.
#include<iostream>
using namespace std;
class Element{
public:
int i;
int j;
int x;
};
class Sparse{
private:
int m;
int n;
int num;
Element *ele;
public: // constructor
Sparse(int n ,int m , int num){
this->n = n;
this->m = m;
this->num = num;
ele = new Element[this->num];
}
~Sparse(){ // destructor
delete []ele;
}
//Global functions for insertion and extraction
Sparse operator+(Sparse &s);
friend istream & operator>>(istream &is , Sparse &s); // Insertion operator
friend ostream & operator<<(ostream &os , Sparse &s); // Extraction operator
};
Sparse Sparse::operator+(Sparse &s)
{
int i , j , k;
if(m!=s.m || n!=s.n)
return NULL;
Sparse *sum = new Sparse(m,n,num+s.num);
i=j=k=0;
while(i<num && j<s.num){
if(ele[i].i < s.ele[j].i){
sum->ele[k++] = ele[i++];
}else if(ele[i].i > s.ele[j].i){
sum->ele[k++] = s.ele[j++];
}else{
if(ele[i].j < s.ele[j].j){
sum->ele[k++] = ele[i++];
}else if(ele[i].j > s.ele[j].j){
sum->ele[k++] = s.ele[j++];
}else{
sum->ele[k]=ele[i];
sum->ele[k++].x = ele[i++].x +s.ele[j++].x;
}
}
}
for(;i<num;i++)sum->ele[k++] = ele[i];
for(;j<s.num;j++)sum->ele[k++] = s.ele[j];
sum->num = k;
return *sum;
}
// void read()
istream & operator>>(istream &is , Sparse &s)
{
cout<<"Enter non zero elements:";
for(int i=0;i<s.num;i++){
cin>>s.ele[i].i>>s.ele[i].j>>s.ele[i].x;
}
return is;
}
// void Display()
ostream & operator<<(ostream &os , Sparse &s)
{
int k = 0;
for(int i= 0; i<s.m;i++){
for(int j=0 ; j<s.n; j++){
if(s.ele[k].i ==i && s.ele[k].j ==j){
cout<<s.ele[k++].x<<" ";
}else{
cout<< "0 ";
}
}
cout<<endl;
}
return os;
}
int main(){
Sparse s1{5,5,5};
Sparse s2{5,5,5};
// s1.read();
// s1.Display();
cin>>s1;
cin>>s2;
Sparse sum=s1+s2;
cout<<"Enter First Matrix:"<<endl<<s1;
cout<<"Enter Second Matrix"<<endl<<s2;
cout<<"Sum Matrix"<<endl<<sum;
return 0;
}
If you go and see the definition of NULL, you will notice that
#define NULL 0
The NULL is replaced by a 0, which is a long int.
In some programming languages, like Java and C#, objects are passed around as pointers, and therefore you can just assign them to null. C++, however, somehow works similar to a struct -- it is passed by value.
Sparse Sparse::operator+(Sparse &s) means that the operator will return a Sparse type. As classes are passed by value, it will return the object's data, a series of bytes. That means you can't just return a NULL to indicate that the concatenation had failed.
An alternative would be to throw an exception. You can also rewrite the operator to a method that returns a Sparse*, a pointer to a Sparse.
Sparse* addSparse(Sparse s1, Sparse s2) {
if(s1.m != s2.m || s1.n != s2.n)
return NULL;
// add them together
}
That way, the caller can check if the concatenation is successful by checking the returned value.
Sparse* result = addSparse(s1, s2);
if(result != NULL) {
// Consume the result
}
// Handle it

Cstring class in C++: Error in +operator?

I'm currently in the second sequence of a C++ course. I'm building my own string class using c-strings & dynamic memory.
I have a majority of my code working. I'm reading in a file and putting each word in a vector of my class type "ATString". We are supposed to combine 5 of the words read in, into a jumbo word, and putting that into another vector. When I use the debugger to step through my code, I see the words combining and it is copying the words over to the new ATString variable "tempJumbo". After a few lines run, the program crashes and tells me my program has triggered a breakpoint, leaving me on line 96 of the addition operator function.
Here the operator+ definition:
ATString ATString::operator+ (ATString& string1) {
int newSize = length() + string1.length();
ATString newString;
if (newSize > 20) { // increase capacity if size is greater than 20 characters
newString.increase_cap();
}
else {
cap = 20;
}
newString.strPtr = new char[newString.cap];
newString.end = newSize;
for (int i = 0; i < length(); i++) {
newString[i] = strPtr[i];
for (int j = length(); j < newSize; j++) {
newString[j] = string1.strPtr[j-end];
}
return newString;
}
And here is main, reading in the file and attempting to combine the words into a jumbo word.
int main() {
vector<ATString> words(100);
vector<ATString> lines(100); // calls default constructor 100 times
ifstream fin("infile3.txt");
int index = 0;
int wordCount = 0;
//READ
if (fin.fail()) {
cout << "Couldn't open infile2.txt" << endl;
system("pause");
exit(1);
}
while (!fin.eof()) {
fin >> words[index];
index++;
}
wordCount = index;
words.resize(wordCount);
//COMBINE 5 WORDS INTO ONE JUMBO
ATString tempJumbo;
int j = 0;
for (int i = 0;i < wordCount; i++) {
tempJumbo = words[i] + words[i+1] + words[i+2] + words[i+3] + words[i+4];
lines[j] = tempJumbo; // putting big word into lines vector
tempJumbo = " "; //resetting variable to hold jumbo word?
i = i + 4;
j++;
if (i == wordCount) {
break;
}
}
return 0;
}
I am also have issues with the destructor I wrote.. it's pretty simple and when I have this activated, it triggers an error as well and crashes the program. Not sure what is going here.
ATString::~ATString() {
delete strPtr;
}
Below is my header file:
#ifndef ATSTRING_H
#define ATSTRING_H
#include <istream>
using namespace std;
class ATString {
public:
ATString();// default constructor
ATString(const char* cstr); // cstring constructor
ATString(const ATString& argstr); // copy constructor
~ATString(); // destructor
ATString& operator = (const ATString& objToCopy); // assignment operator =
ATString operator + (ATString& string1); // addition operator +
int length() const;
int capacity() const;
void increase_cap();
char& operator [] (int index); // indexing operator
const char& operator [] (int index) const; // const indexing operator
bool operator <(const ATString& argstr) ;
bool operator > (const ATString& argstr) ;
bool operator ==(const ATString& argstr);
friend istream& operator >> (istream& inStrm, ATString& argstr); // extraction operator
friend const ostream& operator << (ostream& outStrm, const ATString& argstr); // insertion opertator
private:
char* strPtr;
int end;
int cap;
int compareTo(const ATString& argStr);
};
#endif
THANK YOU!
How big is your input file? If it is 100 words or more, then your index runs out of bounds on the line, when i = 96, i.e. trying to get words[100] element.
tempJumbo = words[i] + words[i+1] + words[i+2] + words[i+3] + words[i+4];

Dynamic matrix in class

I have problem with dynamic allocation in c++.
This is my code:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Wektor {
int rozmiar;
float *TabWe;
friend std::istream& operator >> (std::istream &Strm, Wektor &Wek);
public:
Wektor(int rozmiar) : rozmiar(rozmiar) {
TabWe = new float[rozmiar];
}
Wektor() {
for (int i = 0; i < rozmiar; i++)
{
TabWe[i] = 0;
}
}
~Wektor()
{
for (int i = 0; i <rozmiar; i++)
{
delete[] TabWe;
}
}
};
istream& operator >>(istream &Strm, Wektor &Wek)
{
cout << "Size: ";
Strm >> Wek.rozmiar;
for (int i = 0; i < Wek.rozmiar; i++)
{
Strm >> Wek.TabWe[i];
}
return Strm;
}
int main()
{
Wektor wek;
cin >> wek;
}
After I enter first value to the matrix I get this error:
I think there is problem with default constructor, because you can see on the screenshot that this matrix has no value when program starts. What is wrong with it?

Overloading the input operator with an array of pointers

for a class project I have a 2D array of pointers. I understand the constructors, destructors, etc. but I'm having issues understanding how to set the values in the array. We're using the overloaded input operator to input the values.
Here is the code I have for that operator so far:
istream& operator>>(istream& input, Matrix& matrix)
{
bool inputCheck = false;
int cols;
while(inputCheck == false)
{
cout << "Input Matrix: Enter # rows and # columns:" << endl;
input >> matrix.mRows >> cols;
matrix.mCols = cols/2;
//checking for invalid input
if(matrix.mRows <= 0 || cols <= 0)
{
cout << "Input was invalid. Try using integers." << endl;
inputCheck = false;
}
else
{
inputCheck = true;
}
input.clear();
input.ignore(80, '\n');
}
if(inputCheck = true)
{
cout << "Input the matrix:" << endl;
for(int i=0;i< matrix.mRows;i++)
{
Complex newComplex;
input >> newComplex;
matrix.complexArray[i] = newComplex; //this line
}
}
return input;
}
Obviously the assignment statement I have here is incorrect, but I'm not sure how it is supposed to work. If it's necessary that I include more code, let me know.
This is what the main constructor looks like:
Matrix::Matrix(int r, int c)
{
if(r>0 && c>0)
{
mRows = r;
mCols = c;
}
else
{
mRows = 0;
mCols = 0;
}
if(mRows < MAX_ROWS && mCols < MAX_COLUMNS)
{
complexArray= new compArrayPtr[mRows];
for(int i=0;i<mRows;i++)
{
complexArray[i] = new Complex[mCols];
}
}
}
and here is Matrix.h so you can see the attributes:
class Matrix
{
friend istream& operator>>(istream&, Matrix&);
friend ostream& operator<<(ostream&, const Matrix&);
private:
int mRows;
int mCols;
static const int MAX_ROWS = 10;
static const int MAX_COLUMNS = 15;
//type is a pointer to an int type
typedef Complex* compArrayPtr;
//an array of pointers to int type
compArrayPtr *complexArray;
public:
Matrix(int=0,int=0);
Matrix(Complex&);
~Matrix();
Matrix(Matrix&);
};
#endif
the error I'm getting is "cannot convert Complex to Matrix::compArrayPtr (aka Complex*) in assignment" If anyone can explain what I'm doing wrong, I'd be very grateful.
Your newComplex is an object of type Complex (a value) and you try to assign it to a Complex* pointer.
For this to work you should construct a complex dynamically:
Complex* newComplex = new Complex();
input >> *newComplex;
matrix.complexArray[i] = newComplex;
But be aware of all the consequences that come with dynamic allocation (memory management, ownership, shared state...).

how do i write an overload operator>> function of class string?

class string
{
public:
friend istream& operator >> ( istream& is, string& str);
private:
char *m_data;
};
int main()
{
string str;
freopen("in.txt","r",stdin);
while( cin >> str)
{
cout < < str < < endl;
}
return 0;
}
the content of in.txt are:
asdfsfgfdgdfg
in the overload function, i use is.get() to read those charaters one by one,but program jump out the circle when cin finish,that means cout will not run. on the other way,i try getchar() instead, but it can not jump out the circle.
question: is there any wrong in my idea towards this function? or there is another better way to fulfill. thx :)
=========================================================================================
new edit:
here my code:
#Artem Barger
code detail
#include <iostream>
namespace Str
{
class string
{
public:
string():k(0){}
friend bool operator >> ( std::istream& is, string& str)
{
int size = 100;
char m;
if( (m = getchar()) && m == -1)
return false;
str.m_data = new char[size];
do
{
if( str.k == size)
{
size *= 2;
char *temp = new char[size];
for( int j = 0; j < str.k; ++j)
{
char *del = str.m_data;
temp[j] = *str.m_data++;
delete del;
}
str.m_data = temp;
temp = NULL;
}
str.m_data[str.k++] = m;
}while( (m = getchar()) && m != -1);
return true;
}
friend void operator << ( std::ostream& os, string& str)
{
os << str.m_data;
str.k = 0;
delete []str.m_data;
}
private:
char *m_data;
int k;
};
}
using namespace Str;
int main()
{
string str;
while( std::cin >> str)
{
std::cout << str;
}
return 0;
}
still have some problem in the content of
do
{
}while();
Perhaps you could rewrite your code like this, which should fix your problem:
bool success = true;
while (sucess) {
success = cin >> str;
cout << str;
}
However, I don't understand why you still want the cout to go ahead - if the cin call didn't succeed, you will only be printing the old contents of the string - you do not clear it anywhere (unless you do so in other code which you haven't posted here).