For a class assignment I have to overload the insertion and extraction operators. I'm having trouble getting it to print to the console.
EDITED
Sorry, this is my first time posting. I realize that I didn't post enough info for you guys, I have updated with what should be the necessary code
driver.cpp
#include "mystring.h"
#include <iostream>
using namespace std;
int main(){
char c[6] = {'H', 'E', 'L', 'L', 'O'}
MyString m(c);
cout << m;
return 0;
}
mystring.h
class MyString
{
friend ostream& operator<<(ostream&, const MyString&);
public:
MyString(const char*);
~MyString(const MyString&)
private:
char * str; //pointer to dynamic array of characters
int length; //Size of the string
};
mystring.cpp
#include "mystring.h"
#include <iostream>
#include <cstring>
using namespace std;
MyString::MyString(const char* passedIn){
length = strlen(passedIn)-1;
str = new char[length+1];
strcpy(str, passedIn);
}
MyString::~MyString(){
if(str != NULL){
delete [] str;
}
}
ostream& operator << (ostream& o, const MyString& m){
for(int i = 0; i < strlen(m.str); i++){
o << m.str[i];
}
o.flush();
return o;
}
use the ostream::flush() method. As in:
ostream& operator << (ostream& o, const MyString& m){
for(int i = 0; i < strlen(m.str)-1; i++){
o << m.str[i];
}
o.flush();
return o;
}
Don't try to flush from inside an inserter. None of the standard inserters does that. Just add std::cout << '\n'; after the call to your inserter in main.
The issue here is that std::cout is line buffered. That means it saves the inserted characters in an internal buffer until it sees a newline character (or until it's explicitly flushed). You'll see the same behavior if you insert a std::string object but don't end the line.
Related
I am doing a custom string class in C++. However, when I debugged my code, the system said that:
Error E0415:no suitable constructor exists to convert from "const char" to "string"
Here is my header file where my custom string class is defined:
#ifndef _STRING
#define _STRING
#include <iostream>
class string {
private:
char* s = nullptr;
unsigned int size = 0;
public:
string();
~string() { delete s; };
void operator=(const char*);
friend std::ostream& operator<<(std::ostream&, string&);
};
#endif
string::string()
: s{ nullptr }
{
s = new char[1];
s[0] = '\0';
}
void string::operator=(const char* source)
{
if (source == nullptr) {
s = new char[1];
s[0] = '\0';
}
else {
size = strlen(source) + 1;
s = new char[size];
for (int k = 1; k < (strlen(source) + 1); k++) {
s[k] = source[k];
}
}
}
std::ostream& operator<<(std::ostream& output, string& result)
{
output << result.s;
return output;
}
And here is my main file which I tried to comply:
#include "custom_string.h"
int main()
{
string a;
a = "testfile";
std::cout << a;
system("pause");
return 1;
}
As you can see, I have declared a constructor to convert const char to my custom string by overloading assignment operator. However, there should be something wrong in my code and I could not find out it. Please help me and thank you
Thanks everyone, I have done to fix it. As it turned out, I have to declare one more constructor to covert between my custom string and const char. That is something like this:
string::string(const string& t){}
string& string::operator=(const char&source){}
I need to overload an assignment operator += and concatenate two MyString(class) objects in C++.I'm using CodeBlocks.I need to allocte memory dynamically so I've to use new keyword to overload += operator.The following is the code is used.
MyString.h
#ifndef MYSTRING_H
#define MYSTRING_H
class MyString
{
private:
const char* str;
int length;
public:
MyString();
~MyString();
MyString(const char*);
MyString(const MyString&);
void operator = (const MyString&);
int getLength() const;
MyString operator + (const MyString&);
MyString operator += (const MyString&);
void display();
};
#endif // MYSTRING_H
MyString.cpp
#include "MyString.h"
#include <cstring>
#include <iostream>
MyString::MyString()
{
str="\0";
length=0;
}
MyString::MyString(const char* Str)
{
str=Str;
int str_length=0;
while (str[str_length] != '\0') {
str_length++;
}
length=str_length;
}
MyString::MyString(const MyString &temp)
{
str=temp.str;
length=temp.length;
}
void MyString::operator = (const MyString &deepcopy)
{
str=deepcopy.str;
length=deepcopy.length;
}
MyString MyString::operator += (const MyString& strrr) // here I need to overload assignment operator with new keyword dynamically.
{
str = str+strrr.str; // this is not a correct code.
}
int MyString::getLength() const
{
return length;
}
void MyString::display()
{
std::cout << str<<std::endl;
std::cout << "string length: " <<length<<std::endl;
}
MyString::~MyString()
{
}
main.cpp
#include <iostream>
#include <MyString.h>
int main()
{
char str[20];
MyString S1;
std::cout << "Enter a string : " <<std::endl;
std::cin >> str;
MyString S2(str);
S2.display();
MyString S3=S2;
S3.display();
MyString S4=S3;
S4.display();
MyString S5; // This S5 object that I'm trying to use to overload += operator
S5 = S3 + S4;
S5.display();
return 0;
}
enter code here
Need help figuring out what's the issue with the following source code. I've got a single class to count a number of characters and display each one of them into the console screen.
But unfortunately i kept getting this error message when i tried compiling
error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)
The following are the source files:
CharacterCounter.h
#include <iostream>
class CharacterCounter {
public:
int fTotalNumberOfCharacters;
int fCharacterCounts[256]; // hold all 256 byte values
public:
CharacterCounter();
void count(unsigned char aCharacter);
friend std::ostream& operator<<(std::ostream& aOStream, CharacterCounter& aCharacterCounter);
};
}
CharacterCounter.cpp
#include "CharacterCounter.h"
#include <iostream>
/// Constructor
CharacterCounter::CharacterCounter() {
fTotalNumberOfCharacters = 0;
for (int i=0; i < 256; i++) {
fCharacterCounts[i] = i;
}
}
/// Counts the corresponding data member
void CharacterCounter::count(unsigned char aCharacter) {
fTotalNumberOfCharacters++;
fCharacterCounts[aCharacter]++;
}
/// Output stream displays characters greater than 0
std::ostream& operator<<(std::ostream& aOStream, const CharacterCounter& aCharacterCounter) {
for (int i=0; i < 256; i++) {
if (aCharacterCounter.fCharacterCounts[i] > 0) {
int character = aCharacterCounter.fCharacterCounts[i];
aOStream << (unsigned char)i << ":\t" << character << "\n";
}
}
return aOStream;
}
Main.cpp
#include <iostream>
#include <string>
#include "CharacterCounter.h"
using namespace std;
int main() {
CharacterCounter counter;
unsigned char character;
while (cin >> counter) { **Compilation error focuses here**
counter.count(character);
}
cout << counter;
system("pause");
return 0;
};
You need to overload operator >> for your CharacterCounter, because of cin >> counter, declare it:
class CharacterCounter {
public:
//...
friend std::istream& operator>>(std::istream& input, CharacterCounter& aCharacterCounter);
//...
And then declare function overload:
std::istream &operator>>( std::istream &input, CharacterCounter& aCharacterCounter )
{
input >> aCharacterCounter. fTotalNumberOfCharacters;
// Or input something else or more
return input;
}
I have done this program where I check if my 'date' class is correct. The problem is that when I run my test program, it returned my the following error:
Error in `./bin/test': double free or corruption (fasttop): 0x00000000019c07c0 *
The job of this class is read and store a 'date'(a year) and a few events (allocated in a string array). For example, a object of this class would be: 1998 EVENT1 EVENT2 EVENT3.
Operator >> reads the next format:1908#Fantasmagorie#The Taming of the Shrew#The Thieving Hand#The Assassination of the Duke of Guise#A Visit to the Seaside
Well, my problem is that I'm deleting some pointer twice or freeing some memmory twice, I have tried a lot of things but I don't know how to fix it (as you can see on my code, I have already tried to set all pointers to 0 when I delete them.):
Date class .h
#ifndef _date_HISTORICA_
#define _date_HISTORICA_
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
class date{
private:
int year;
int eventsNum;
int reserved;
string * str;
void resize(int r);
public:
date();
//date(int a, string *s, int n);
date(const date& d);
~date();
int getAge();
void addEvent(string& s);
friend ostream& operator<<(ostream& os, const date& d);
friend istream& operator>>(istream& is, date& d);
};
#endif
Date Class Code:
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<date.h>
using namespace std;
void date::resize(int r)
{
assert(r>=0);
if(r!=this->reserved)
{
if(r!=0)
{
string * aux = new string[r];
if(this->reserved>0)
{
int min=this->reserved<r?this->reserved:r;
for(int i=0; i<min; i++)
aux[i]=this->str[i];
delete[] this->str;
this->str=NULL;
}
this->str=aux;
this->reserved=r;
if(this->reserved<this->eventsNum)
this->eventsNum=this->reserved;
} else
{
if(this->reserved>0)
{
delete[] this->str;
this->str=NULL;
}
this->year=0;
this->eventsNum=0;
this->reserved=0;
}
}
}
date::date() : year(0), eventsNum(0), reserved(0), str(0){}
date::date(const date& d)
{
this->year=d.year;
this->eventsNum=d.eventsNum;
this->reserved=d.reserved;
this->str=new string[this->reserved];
for(int i=0; i<this->eventsNum; i++)
this->str[i]=d.str[i];
}
date::~date()
{
this->year=0;
this->eventsNum=0;
this->reserved=0;
if(this->str)
delete[] this->str;
this->str=NULL;
}
int date::getAge(){return this->year;}
ostream& operator<<(ostream& os, const date& d)
{
os << d.year;
for(int i=0; i<d.eventsNum; i++)
os << '#' << d.str[i];
os << endl;
return os;
}
void date::addEvent(string& s){
if (this->eventsNum == this->reserved){
if (this->eventsNum==0)
resize(1);
else
resize(2*this->reserved);
}
this->str[eventsNum]=s;
eventsNum++;
}
istream& operator>>(istream& is, date& d)
{
string line; char c;
is >> d.year >> c;
getline(is, line);
int n=1;
for(int i=0; i<line.length(); i++)
if(line[i]=='#')
n++;
d.eventsNum=n;
d.reserved=d.eventsNum;
delete[] d.str;
d.str=NULL;
d.str=new string[n];
stringstream ss(line);
for(int i=0; i<n; i++)
getline(ss, d.str[i], '#');
return is;
}
Test Program Class:
#include<iostream>
#include<fstream>
#include<cronologia.h>
#include<date.h>
using namespace std;
int main(int argc, char * argv[]){
cout << "STATE: IN PROGRESS" << endl;
cout << "TEST: (2)" << endl;
date d;
ifstream f("./data/name.txt");
while(f >> d)
{
cout << d;
}
date d1;
cin >> d1;
d=d1;
cout << d << endl;
}
Example file (wich should be read by date clas):
1900#Sherlock Holmes Baffled#The Enchanted Drawing
1901#Star Theatre#Scrooge, or, Marley's Ghost
1902#A Trip to the Moon
1903#The Great Train Robbery#Life of an American Fireman
1904#The Impossible Voyage
1905#Adventures of Sherlock Holmes; or, Held for Ransom
1906#The Story of the Kelly Gang#Humorous Phases of Funny Faces#Dream of a Rarebit Fiend
1907#Ben Hur#L'Enfant prodigue
1908#Fantasmagorie#The Taming of the Shrew#The Thieving Hand#The Assassination of the Duke of Guise#A Visit to the Seaside
Im so sorry for my English!!! :,(
Since there is no assignment overloading in your code, in the line
d=d1;
All the members of d1 will be copied to a new object d by value. Hence there will be two copies of the object date which have the same reference value in their member str. Those two will eventually get out of scope and both will be destructed. The first one will free the allocated memory while the other will try to free that same reference and that is why you get the error.
You need a copy assignment operator:
void swap(date& other)
{
using std::swap;
swap(year, other.year);
swap(eventsNum, other.eventsNum);
swap(reserved, other.reserved);
swap(str, other.str);
}
date::date(const date& d) : year(other.year), eventsNum(other.eventsNum), reserved(other.reserved), str(new string[other.reserved])
{
for(int i = 0; i < this->eventsNum; i++)
this->str[i] = d.str[i];
}
date& date::operator = (const date& d)
{
swap(*this, d);
return *this;
}
Might also be nice to provide a move constructor..
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a problem and I can't solve it.
note: I can't use any string/strlen/strcmp and such functions
My problem is when I'm trying to print obj after cin, when I don't put him value it prints garbage, and if I put value it change it by cin it print it well.
#ifndef __STRING_H__
#define __STRING_H__
#include <iostream>
using namespace std;
class String {
private:
char* Str; //pointer to string
int Str_s; // size of string public:
String(char* str = NULL);
~String();
void const print() const; //check
//~~~~~~~~~~~~~~~~~~
// operators
//~~~~~~~~~~~~~~~~~
String& operator=(const String& str);
bool operator==(const String& s) const;
bool operator!=(const String& s) const;
void operator-=(const char c);
void operator+=(const char c);
char& operator[](const int index) const;
//~~~~~~~~~~~~~~~~~~
// i/o ~~ operators
//~~~~~~~~~~~~~~~~~
friend ostream& operator<<(ostream&, const String& s);
friend istream& operator>>(istream&, String& s);
//~~~~~~~~~~~~~~~~~~
// arrange method
//~~~~~~~~~~~~~~~~~
void Letters(); // arrange all letter in sentence
void Space(); //remove all unwanted spaces
void Set_Str_s(int num) {
this->Str_s = num;
}
int Get_Str_s() {
return this->Str_s;
}
//~~~~~~~~~~~~~~~~~~
// methods
//~~~~~~~~~~~~~~~~~
char const* STR() {
return Str;
}
};
#endif
ostream& operator<<(ostream& output, const String& s) {
//char *c = s.Str;
//output << c << endl;
for (int i = 0; i < s.Str_s; i++) {
cout << s.Str[i];
}
return output;
}
istream& operator>>(istream& input, String& s) {
if (s.Str == NULL) {
s.Str_s = 0;
char temp[BUFFER];
int i = 0, j = 0;
cin.getline(temp, BUFFER);
while (temp[i] != NULL) {
s.Str_s++;
i++;
}
//s.Str = new char[s.Str_s];
s.Str = temp;
} else {
input >> s.Str;
}
return input;
}
#include <iostream>
using namespace std;
#include "string_head.h"
#include "Definition_head.h"
#include "Menu_head.h"
int main() {
char* c = "hi";
char* h = "lilo";
String s, m(c);
cin >> s;
cin >> m;
cout << s;
cout << endl;
cout << m;
}
The following line is a problem:
s.Str = temp;
you are storing a pointer to a local array that will be deleted when the function returns. Use something like:
s.Str = strdup(temp);
If your platform doesn't support strdup, you can implement it. It's not too hard.
The following line is also a problem:
input >> s.Str;
If there isn't enough memory to hold the string being read, you will be writing into memory that you are not supposed to.