Input Stream Invalid read/write of size 1 - c++

i've been absolutely lost on this topic. I wrote my own String class and tried running it in valgrind to see of it really works. Valgrind tells me that i got a lot of invalid read's and write's.
Basically what im trying to do is feed it a String Value and read it's contents later on. For this i defined following Header file.
#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED
#include<iostream>
#include<istream>
#include<ostream>
class string{
public:
string(char* = nullptr);
~string();
string(const string&);
friend std::istream& operator>>(std::istream&,string&);
friend std::ostream& operator<<(std::ostream&,string&);
bool operator<(const string&);
bool operator==(const string&);
void setContent(char*);
char* getContent() const;
private:
unsigned getSize() const;
void copyStr(char*,char*);
unsigned getCharl(const char*)const;
string& operator=(const string&);
char* s = nullptr;
};
#endif // STRING_H_INCLUDED
The CPP for the Header looks like the following.
#include<iostream>
#include<ostream>
#include "string.h"
string::string(char* i){
if(i == nullptr){
s = new char[1];
s[0] = '\0';
}else{
s = new char[getCharl(i)+1];
copyStr(s,i);
}
}
string::~string(){
if(s != nullptr){
delete s;
}
}
unsigned string::getCharl(const char* i) const{
const char* ende = i;
for(; *ende != '\0';++ende)
;
return ende-i;
}
void string::copyStr(char* s,char* i){
unsigned index = 0;
s = new char[getCharl(i)+1];
while (i[index] != '\0'){
s[index] = i[index];
index++;
}
s[index] = '\0';
}
bool string::operator<(const string& s1){
if(getSize()<s1.getSize()){
return true;
}else if(getSize()>s1.getSize()){
return false;
}else{
for(unsigned i = 0; i < s1.getSize();++i){
if(getContent()[i] != s1.getContent()[i]){
if(getContent()[i]<s1.getContent()[i]){
return true;
}else{
return false;
}
}
}
return false;
}
}
string::string(const string& x){
delete s;
s = new char[x.getSize()];
char* tmp = x.getContent();
unsigned index = 0;
while (tmp[index] != '\0'){
this->s[index] = x.s[index];
index++;
}
}
char* string::getContent() const{
return s;
}
void string::setContent(char* v){
s = v;
}
string& string::operator=(const string& x){
if(this == &x)
return *this;
if(&x != this){
delete getContent();
setContent(nullptr);
setContent(new char[x.getSize()]);
}
copyStr(getContent(),x.getContent());
return *this;
}
bool string::operator==(const string& l){
if(getSize() == l.getSize()){
unsigned length = getSize();
for(unsigned i = 0; i < length;++i){
if(getContent()[i] != l.getContent()[i])
return false;
}
return true;
}
return false;
}
std::istream& operator>>(std::istream& is, string& arg){
return is >> arg.s;
}
std::ostream& operator<<(std::ostream& os, string& arg){
return os << arg.getContent();
}
unsigned string::getSize() const{
unsigned length = 0;
while(s[length]){
++length;
}
++length;
return length;
}
Basically i would be pretty happy to know why i get an error in my operator>> where i try to write a char* Array to my char* s.
And i would like to know why i get an error in my function getSize() in the while-loop. (Error appears at s[length]).
Maybe someone is so kind to explain me the reasons.
Cheers!
Edit:
Modified the program now to look like the following implementing the comments.
#include<iostream>
#include<ostream>
#include "string.h"
string::string(char* i){
if(i == nullptr){
s = new char[1];
s[0] = '\0';
}else{
s = new char[getCharl(i)+1];
copyStr(i);
}
}
string::~string(){
if(s != nullptr){
delete[] s;
}
}
unsigned string::getCharl(const char* i) const{
const char* ende = i;
for(; *ende != '\0';++ende)
;
return ende-i;
}
void string::copyStr(char* i){
unsigned index = 0;
delete[] s;
char* tmp = new char[getCharl(i)+1];
while (i[index] != '\0'){
tmp[index] = i[index];
index++;
}
tmp[index] = '\0';
s = tmp;
}
bool string::operator<(const string& s1){
if(getSize()<s1.getSize()){
return true;
}else if(getSize()>s1.getSize()){
return false;
}else{
for(unsigned i = 0; i < s1.getSize();++i){
if(getContent()[i] != s1.getContent()[i]){
if(getContent()[i]<s1.getContent()[i]){
return true;
}else{
return false;
}
}
}
return false;
}
}
string::string(const string& x){
copyStr(x.getContent());
}
char* string::getContent() const{
return s;
}
void string::setContent(char* v){
s = v;
}
string& string::operator=(const string& x){
if(this == &x)
return *this;
if(&x != this){
delete[] getContent();
setContent(nullptr);
setContent(new char[x.getSize()]);
}
copyStr(x.getContent());
return *this;
}
bool string::operator==(const string& l){
if(getSize() == l.getSize()){
unsigned length = getSize();
for(unsigned i = 0; i < length;++i){
if(getContent()[i] != l.getContent()[i])
return false;
}
return true;
}
return false;
}
std::istream& operator>>(std::istream& is, string& arg){
is >> arg.s;
return is;
}
std::ostream& operator<<(std::ostream& os, string& arg){
return os << arg.getContent();
}
unsigned string::getSize() const{
unsigned length = 0;
while(getContent()[length]){
++length;
}
++length;
return length;
}
Still the problem with the operator>> exists and also now im getting errors in getCharl in the for loop and copyStr im the while loop. (invalid read)
If someone would be so kind and explain to me why.

Related

Repeating words in string class

So I have to write a string class, and I need help with reading from a file into a vector of string classes I've created. It somewhat works, as it reads from the file but it repeats the the word read in a few times depending on which word it's on.
// .h
/*Class description:
A string class. Various functions for the class.
String is passed into objects of the class. Reads
and writes to files.*/
#ifndef MYString12_H
#define MYString12_H
#include <fstream>
using namespace std;
class MYString12
{
public:
MYString12();
MYString12(const MYString12 & mstr);
MYString12(const char* ptr);
~MYString12();
MYString12& operator = (const MYString12& argStr);
friend MYString12 operator + (const MYString12& str1, const MYString12& str2);
char operator [] (int index);
bool operator > (const MYString12& argStr2);
bool operator < (const MYString12& argStr2);
bool operator == (const MYString12& argStr);
friend istream& operator >> (istream& istr, MYString12& argStr);
friend ostream& operator << (ostream& istr, MYString12& argStr);
int length() const;
int capacity()const;
char at(int index);
const char* c_str()const;
static int getCurrentCount();
static int getCreatedCount();
private:
char* str;
int cap = 20;
int end;
const int compareTo(const MYString12& argStr);
static int currentCount;
static int createdCount;
};
#endif
Here is class cpp file
// MYString12.cpp
#include "stdafx.h"
#include "MYString12.h"
#include <iostream>
#include <iomanip>
#include <math.h>
#include <cstdlib>
using namespace std;
int MYString12::createdCount = 0;
int MYString12::currentCount = 0;
// default constructor
MYString12::MYString12()
{
cap = 20;
end = 0;
str = new char[cap];
str[end] = '\0';
createdCount++;
currentCount++;
}
// copy constructor
MYString12::MYString12(const MYString12& mstr)
{
this->end = mstr.end;
this->cap = mstr.cap;
this->str = new char[mstr.cap];
while (end >= cap) {
cap += 20;
}
for (int i = 0; i < end; i++) {
str[i] = mstr.str[i];
}
//mstr.str[end] = '\0';
createdCount++;
currentCount++;
}
// constructor with string passed in
MYString12::MYString12(const char* ptr)
{
int i = 0;
while (ptr[i] != '\0') {
end++;
i++;
}
while (end >= cap) {
cap += 20;
}
str = new char[cap];
for (int j = 0; j < end; j++) {
str[j] = ptr[j];
}
createdCount++;
currentCount++;
}
// destructor
MYString12::~MYString12()
{
delete[] str;
currentCount--;
}
// overloaded assignment operator
GAString12& GAString12::operator = (const GAString12& mstr)
{
if (this == &mstr) {
return *this;
}
this->end = mstr.end;
this->cap = mstr.cap;
while (end >= cap) {
cap += 20;
}
for (int i = 0; i < end; i++) {
str[i] = mstr.str[i];
}
//mstr.str[end] = '\0';
return *this;
}
// overloaded concatanation operator
MYString12 operator + (const MYString12& str1, const MYString12& str2)
{
int temp = str1.end + str2.end + 1;
char tempArray[200];
int i = 0;
int j = 0;
while (i < temp)
{
if (i < str1.end)
{
tempArray[i] = str1.str[i];
i++;
} else {
tempArray[i] = str2.str[j];
i++;
j++;
}
}
tempArray[i] = '\0';
MYString12 concatenatedObj(tempArray);
return concatenatedObj;
}
// overloaded index operator
char MYString12::operator [] (int index)
{
return str[index];
}
// overloaded greater than operator
bool MYString12::operator > (const MYString12& argStr)
{
if ((*this).compareTo(argStr) > 0)
{
return true;
}
else {
return false;
}
}
// overloaded less than operator
bool MYString12::operator < (const MYString12& argStr)
{
if ((*this).compareTo(argStr) < 0)
{
return true;
}
else {
return false;
}
}
// overloaded equals equals operator
bool MYString12::operator == (const MYString12& argStr)
{
if ((*this).compareTo(argStr) == 0)
{
return true;
}
else {
return false;
}
}
// compares ascii values of objStr and argStr
const int MYString12::compareTo(const MYString12& argStr)
{
int asciiSubtraction = 0;
int limit = 0;
if (end <= argStr.end)
{
limit = end;
}
else {
limit = argStr.end;
}
int i = 0;
while (i <= limit && (str[i] == argStr.str[i])) {
i++;
}
asciiSubtraction = str[i] - argStr.str[i];
return asciiSubtraction;
}
// overloaded extraction operator
istream& operator >> (istream& istr, MYString12& argStr)
{
char temp[100];
istr >> temp;
argStr = GAString12(temp);
return istr;
}
// overloaded insertion operator
ostream& operator << (ostream& ostr, MYString12& argStr)
{
int i = 0;
while (argStr.str[i] != '\0')
{
ostr << argStr.str;
i++;
}
return ostr;
}
// returns size of passed in string
int MYString12::length() const
{
return end;
}
// returns size of memory allocated
int MYString12::capacity() const
{
return cap;
}
// returns a char of string at passed index
char MYString12::at(int index)
{
if (index < 0 || index > end) {
return '\0';
}
else {
return str[index];
}
}
// returns passed in string as c string
const char* MYString12::c_str() const
{
createdCount++;
currentCount++;
return str;
}
// returns the amount of alive instances of class
int MYString12::getCurrentCount()
{
return currentCount;
}
// returns the amount of overall created instances of class
int MYString12::getCreatedCount()
{
return createdCount;
}
And here is main
// main
int main()
{
vector<MYString12> word(100);
ifstream fin;
fin.open("infile3.txt");
if (fin.fail()) {
cout << "Error." << endl;
exit(1);
}
int wordCount = 0;
while (fin >> word[wordCount]) {
cout << word[wordCount];
system("pause");
wordCount++;
}
word.resize(wordCount);
fin.close();endl;
return 0;
}
It doesn't print out to the console any of the words. Nothing is printed. Why doesn't it print?

Why it's not possible to assign std::string to a subtring?

This is the code for my project which I want to compile. The error is stated at the end of the question.
#include <iostream>
#include <string>
#include <stdio.h>
class substring {
friend std::ostream& operator<<(std::ostream& output, substring const& sub);
public:
char *str;
int length;
substring();
~substring();
substring(std::string);
substring(const substring &);
substring& operator=(substring const& other);
substring& operator=(std::string const& strz);
substring& operator+=(substring const& other);
bool operator>(substring const& other) const;
bool operator<(substring const& other) const;
char& operator[](size_t idx);
char operator[](size_t idx) const;
};
std::ostream& operator<<(std::ostream& output, substring const& sub);
std::istream& operator >> (std::istream& input, substring const& sub);
bool operator==(substring const& one, substring const& another);
bool operator!=(substring const& one, substring const& another);
bool operator==(std::string const& str, substring const& sub);
bool operator==(substring const& sub, std::string const& str);
bool operator!=(std::string const& str, substring const& sub);
bool operator!=(substring const& sub, std::string const& str);
substring::substring()
{
length = 0;
}
substring::~substring()
{
delete str;
}
substring::substring(std::string)
{
}
substring::substring(const substring & sub)
{
str = new char[length];
}
std::ostream & operator<<(std::ostream & output, substring const & sub)
{
output << sub;
return output;
}
std::istream & operator >> (std::istream & input, substring const & sub)
{
std::cout << "Enter sub:";
input >> sub;
return input;
}
bool operator==(substring const & one, substring const & another)
{
if (one.length != another.length)
return false;
else
{
for (int i = 0; i < another.length; i++)
if (one[i] != another[i])
{
return false;
break;
}
}
return true;
}
bool operator!=(substring const & one, substring const & another)
{
if (one.length != another.length)
return true;
else
{
for (int i = 0; i < another.length; i++)
if (one[i] != another[i])
{
return true;
break;
}
}
return false;
}
bool operator==(std::string const & str, substring const & sub)
{
if (sub.length != str.length())
return false;
else
{
for (int i = 0; i < sub.length; i++)
if (str[i] != sub[i])
{
return false;
break;
}
}
return true;
}
bool operator==(substring const & sub, std::string const & str)
{
if (str.length() != sub.length)
return false;
else
{
for (unsigned int i = 0; i < str.length(); i++)
if (sub[i] != str[i])
{
return false;
break;
}
}
return true;
}
bool operator!=(std::string const & str, substring const & sub)
{
if (sub.length != str.length())
return true;
else
{
for (int i = 0; i < sub.length; i++)
if (str[i] != sub[i])
{
return true;
break;
}
}
return false;
}
bool operator!=(substring const & sub, std::string const & str)
{
if (sub.length != str.length())
return true;
else
{
for (int i = 0; i < sub.length; i++)
if (str[i] != sub[i])
{
return true;
break;
}
}
return false;
}
substring & substring::operator=(substring const & other)
{
delete str;
length = other.length;
str = new char[length];
for (int i = 0; i<length; i++)
{
str[i] = other.str[i];
}
return *this;
}
substring & substring::operator=(std::string const & strz)
{
length = strz.length();
str = new char[length];
for (int i = 0; i<length; i++)
{
str[i] = strz[i];
}
return *this;
}
substring & substring::operator+=(substring const & other)
{
char* new_str = new char[length + other.length];
for (int i = 0; i<length; i++)
{
new_str[i] = str[i];
}
for (int i = length; i<other.length; i++)
{
new_str[i] = other.str[i];
}
delete str;
str = new_str;
return *this;
}
bool substring::operator>(substring const & other) const
{
return true;
}
bool substring::operator<(substring const & other) const
{
return true;
}
char & substring::operator[](size_t idx)
{
return str[idx];
}
char substring::operator[](size_t idx) const
{
return str[idx];
}
int main()
{
std::string str = "abc";
substring sub = str;
std::cout << sub;
return 0;
}
The problem is that when I run this code, it seems that the compiler just skips this: substring sub = str;.
I cannot even change this line to substring sub = "aaa"; because it shows an error which says I cannot convert subtring to std::string (although there is an operation overloading for this in the code).
The problem is that when I run this code, it seems that the compiler just skips this: substring sub = str;
The compiler did not "skip it". It compiled succesfully, and the new object was created succesfully. However, the converting constructor that you defined leaves the objects members default initialized:
substring::substring(std::string)
{
}
I cannot even change this line to substring sub = "aaa"; because it shows an error which says I cannot convert subtring to std::string
I highly doubt that. I suspect that you misread.
My compiler says that const char [4] cannot be converted substring
(although there is an operation overloading for this in the code).
There certainly isn't a substring::substring(const char(&)[4]) (nor substring::substring(const char*)).

segmentation fault scrabble game

im working on a little scrabblegame which i read a txtfile and create a hashtable for all words inside. Word is a specific class which contains a vector of .
i want to create a hashmap by my own and define the length of my "Dictionary" is 50000. im using a nullpointer to reserve all index of my array. If i want to print to my hashtable, compiler tells me a segmentation fault. does any one seems the error?
the headerfile:
class Dictionary {
public:
Dictionary();
Dictionary(string filepath);
friend std::ostream& operator<<(std::ostream& os, const Dictionary& obj);
bool find(const Word& word);
vector<Word> allPossibleWords(const vector<Character>& tiles);
// struct compare {
//
// bool operator()(const Word& a, const Word& b) {
// return a.operator<(b);
// }
// } myCompare;
vector<Word> m_allWords;
vector<Word>::iterator itVecWords;
static const int table_size = 500000;
// std::array <Word*, table_size> arrWords = {nullptr};
Word* arrWords[table_size] = {nullptr};
int hash(Word new_word);
void addItem(Word word);
void printHashTable();
the cpp:
Dictionary::Dictionary(string filepath) {
ifstream datei(filepath.c_str());
while (datei.good() && !datei.eof()) {
string temp;
string temp1;
string::size_type pos;
getline(datei, temp);
pos = temp.find(" ");
temp1 = temp.substr(0, pos);
Word new_word(temp1);
addItem(new_word);
}
datei.close();
}
std::ostream& operator<<(std::ostream& os, const Dictionary& obj) {
for (int i = 0; i < obj.m_allWords.size(); i++) {
os << obj.m_allWords[i] << endl;
}
return os;
}
bool Dictionary::find(const Word& word) const {
if (std::binary_search(m_allWords.begin(), m_allWords.end(), word)) {
return true;
}
return false;
}
vector<Word> Dictionary::allPossibleWords(const vector<Character>& tiles) const {
vector<Word> ergebnis;
string tmp;
int cnt = 0;
for (int i = 0; i < tiles.size(); i++) {
tmp += tiles[i].GetC();
}
sort(tmp.begin(), tmp.end());
for (int i = 1; i <= tiles.size(); i++) {
do {
string piece = tmp.substr(0, i);
do {
Word search = Word(piece);
//Überschreibt immer der in Ergebnis existierte Wert
if (find(search) && std::find(ergebnis.begin(), ergebnis.end(), search) == ergebnis.end()) {
ergebnis.push_back(search);
}
} while (next_permutation(piece.begin(), piece.end()));
} while (next_permutation(tmp.begin(), tmp.end()));
}
return ergebnis;
}
int Dictionary::hash(Word new_word) {
int index = 0;
for (auto u : new_word.new_Character) {
index += (int) u.GetC();
}
index = index * (int) new_word.new_Character.at(0).GetC();
index = index * (int) new_word.new_Character.at(new_word.new_Character.size() - 1).GetC();
return index % table_size;
}
void Dictionary::addItem(Word word) {
int index = hash(word);
if (arrWords[index] == nullptr) {
arrWords[index] = new Word(word);
} else {
Word* ptr = arrWords[index];
Word* neu = new Word(word);
while (ptr->getNextWord() != nullptr) {
ptr = ptr->getNextWord();
}
ptr->setNextWord(neu);
}
}
void Dictionary::printHashTable() {
Word* tmp;
for (int i = 0; i < table_size; i++) {
tmp = arrWords[i];
if (tmp != nullptr) {
tmp->printWord();
cout << "Index : " << i;
}
tmp = tmp->getNextWord();
}
}
class Word {
public:
Word();
Word(string m_wort);
int length() const;
int points() const;
friend std::ostream& operator<<(std::ostream& os, const Word& obj);
bool operator==(const Word& right) const; /
bool operator!=(const Word& right) const;
bool contains(const Character& c) const;
Word substr(int start, int end) const;
bool operator<(const Word& right) const;
vector <Character> new_Character;
Word* Next = nullptr;
void setNextWord(Word*);
Word* getNextWord();
void printWord();
string getWordAsString();
CPP File:
void Word::setNextWord(Word* w) {
Next = w;
}
Word* Word::getNextWord() {
return Next;
}
void Word::printWord() {
string s = "";
for (int i = 0; i < new_Character.size(); i++) {
s += new_Character.at(i).GetC();
}
cout << s << endl;
}
string Word::getWordAsString() {
string s;
for (int i = 0; i < new_Character.size(); i++) {
s += new_Character.at(i).GetC();
}
return s;
}

Don't understand a seg fault

String is my own string class and Stack is my own stack class.
I am trying to change infix to postfix with values that are separated by spaces.
The function below pretty much works but also returns a "Segmentation fault (core dumped)".
String postfix(String infix){
std::vector<String> vec;
vec = infix.split(' ');
Stack<String> tmp;
String right, left, op;
int i = 0;
while (vec[i] != ';'){
if (vec[i] == ')'){
right = tmp.pop();
op = tmp.pop();
left = tmp.pop();
tmp.push(left + ' ' + right + ' ' + op);
}else{
if (vec[i] != '(' && vec[i] != ' ')
tmp.push(vec[i]);
}
++i;
}
String postfix = tmp.pop();
return postfix;
}
I do not understand why this is. Any help would be appreciated.
#ifndef STACK_HPP
#define STACK_HPP
template <typename T>
class Node{
public:
T data;
Node<T>* next;
Node() { data().next(0); } ;
Node (const T& x) : data (x), next(0) {};
};
template <typename T>
class Stack{
public:
Stack() : tos(0){};
~Stack();
Stack(const Stack<T>&);
void swap(Stack<T>& rhs);
Stack<T>& operator= (Stack<T> rhs) { swap(rhs); return *this; };
bool isEmpty() const { return tos == 0; };
T pop();
void push(const T&);
private:
Node<T> *tos;
};
///////////////////////////////////////////////////////////////
template <typename T>
Stack<T>::~Stack(){
while(tos != 0){
Node<T> *tmp = tos;
tos = tos -> next;
delete tmp;
}
}
template <typename T>
void Stack<T>::swap(Stack<T>& rhs){
Node<T> *tmp = tos;
tos = rhs.tos;
rhs.tos = tmp;
}
template <typename T>
Stack<T>::Stack(const Stack<T>& actual){
Node<T> *tmp = actual.tos, *bottom = 0;
tos = 0;
while (tmp != 0){
if(tos == 0){
tos = new Node<T>(tmp -> data);
bottom = tos;
}else{
bottom -> next = new Node<T>(tmp -> data);
bottom = bottom -> next;
}
tmp = tmp -> next;
}
}
template<typename T>
T Stack<T>::pop(){
T result = tos -> data;
Node<T> *tmp = tos;
tos = tos -> next;
delete tmp;
return result;
}
template <typename T>
void Stack<T>::push(const T& x){
Node<T> *tmp = new Node<T> (x);
tmp -> next = tos;
tos = tmp;
}
#endif
//bruce pucci
//string
//cs23001
#include <iostream>
#include <cassert>
#include <vector>
#include <fstream>
#include "string.hpp"
///////////////////////////////string class friend functions////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////I/O/////////////////////////////////////////////
std::ostream& operator<<(std::ostream& out, const String& print){//std::cout operator
int i = 0;
while (print.arr[i] > 0){
out << print.arr[i];
++i;
}
return out;
}
std::ifstream& operator>>(std::ifstream& in, String& rhs){//ifstream operator.
char tmp[stringSize];//grabs word by word (chars serperated by whitespace).
in >> tmp;
rhs = String(tmp);
return in;
}
////////////////////////////////string class public functions///////////////////////
////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////constructors///////////////////////////////////////
String::String(){//default constructor. default size
arr = new char[stringSize];
cap = stringSize;
arr[0] = 0;
}
String::String(const char a){//char constructor. default size
arr = new char[stringSize];
cap = stringSize;
arr[0] = a;
arr[1] = 0;
}
String::String(const char a[]){//char array constructor. default size
arr = new char[stringSize];
cap = stringSize;
int i = 0;
while (a[i] > 0){
arr[i] = a[i];
++i;
}
arr[i] = 0;
}
String::String(const int initSize, const char a[]){//char array constructor. size passed as a parameter
arr = new char[initSize];
cap = initSize;
int i = 0;
while (a[i] > 0){
arr[i] = a[i];
++i;
}
arr[i] = 0;
}
String::String(int initSize){//like default constructor. size passed as parameter
arr = new char[initSize];
cap = initSize;
}
//////////////////////////////////dynamic stuff/////////////////////////////////////////////////
String::String(const String& rhs){//big three. copy constructor
arr = new char[rhs.cap];
cap = rhs.cap;
for (int i = 0; i < cap; ++i)
arr[i] = rhs.arr[i];
}
String::~String(){//big three. destuctor.
delete [] arr;
}
String& String::operator=(String rhs){//big three. assignment operator.
swap(rhs);
return *this;
}
String String::swap(String& rhs){//swap the pointers on 2 char arrays.
int tmpCap = rhs.cap;
rhs.cap = cap;
cap = tmpCap;
char* tmp = rhs.arr;
rhs.arr = arr;
arr = tmp;
return *this;
}
///////////////////////////////////functions////////////////////////////////////////////////////////////////
void String::reallocate(int a){//changes the size of a dynamic String. size passed as parameter.
String tmp;
tmp.cap = a;
tmp.arr = new char[a];//allocate space of size passed.
int i = 0;
while (arr[i] != 0){//copy elements to newly allocated tmp array
tmp.arr[i] = arr[i];
++i;
}
tmp.arr[i] = 0;
swap(tmp);//swap pointers of tmp and passed array
}
std::vector<String> String::split(char splitter) const{//splits a String into a vecotr of
std::vector<String> vecOfStrings;//Strings besed on the delimited passed
int start = 0, end = 0;//returns that vector
bool doIt = false;
for (int i = 0; i < cap; ++i){//look if the delimiter exists
if (arr[i] == ' '){
doIt = true;
break;
}
}
if (doIt){//if the delimiter exists in the string start looping
for (int i = 0; i < cap; ++i){
if (arr[i] == splitter){//when each occurance of the delimiter is found create a
end = i;//node of String in the vector with the chars since the previous node
vecOfStrings.push_back(substr(start, end - 1));
start = (end + 1);
}
if (i == (cap - 1)){//do this until the no more delimiters are found
end = i;
vecOfStrings.push_back(substr(start, end));
}
}
}
return vecOfStrings;
}
int String::length() const{//returns the length of the String before the terminating char.
int counter = 0;
while (arr[counter] != 0)
++counter;
return counter;
}
int String::capacity() const{//accessor to capacity.
return cap;
}
String String::substr(int start, int end) const{//returns a subset string of string passed.
if ((start < 0) || (end < 0))//parameters are starting and ending points of the substring
return String();
String result;
int returnIndex = start;
for (int i = start; i <= end; ++i)
result[i - start] = arr[returnIndex++];
result[end - start + 1] = 0;
return result;
}
int String::findChar(const char target) const{//returns the position of the first occurance of the char
for (int i = 0; i < length(); ++i)//being searched for. returns -1 if the char is not found.
if (arr[i] == target)
return i;
std::cout << "The char was not found." << std::endl;
return -1;
}
int String::findStr(const char target[]) const{//searches for a substring in the string. returns the
String targetString(target);//position of the first char in the substring
return findStr(targetString);//uses the String version of findStr. look there for more info.
}
int String::findStr(const String& target) const{//searches for a substring in the string. returns the
int targetLength = target.length();//position of the first char in the substring
String candidate;//candidate is the string that
int candStart = 0, candEnd = candStart + (targetLength - 1), i = 0;//will be compared to other strings
//of the same length
while (i < (stringSize - targetLength)){//go through char by char and compare candidate to
candidate = substr(candStart++, candEnd++);//strings of the same length within the full string.
if (candidate == target)//ex String = "Hello World." looking for "llo"
return i;//"Hel" == "llo" no "Hel" == "ell" no "llo == "llo" yes.
i++;//return 2.
}
std::cout << "The string was not found." << std::endl;
return -1;//if not found at all return -1
}
int String::stringToInt(){
int result = 0, intTmp;
char charTmp;
for (int i = 0; i < length(); ++i){
charTmp = arr[i];
switch (charTmp){
case '0' : intTmp = 0; break;
case '1' : intTmp = 1; break;
case '2' : intTmp = 2; break;
case '3' : intTmp = 3; break;
case '4' : intTmp = 4; break;
case '5' : intTmp = 5; break;
case '6' : intTmp = 6; break;
case '7' : intTmp = 7; break;
case '8' : intTmp = 8; break;
case '9' : intTmp = 9; break;
case '-' : intTmp = 0; break;
}
if (result > 0)
result = result * 10;
result = result + intTmp;
}
return result;
}
/////////////////////////////////////////////operators////////////////////////////////////////////////////////////////////
char String::operator[](int i) const{//subscript operator. returns char whated in char array. const version.
return arr[i];//acts as an accessor to chars
}
char& String::operator[](int i){//subscript operator. returns char whated in char array. non const version.
return arr[i];//acts as an accessor to chars
}
String String::operator+(const String& rhs) const{//concatenate
String result(arr);
int start = length(), rhsIndex = 0;
while (rhs.arr[rhsIndex] != 0){
result.arr[start] = rhs.arr[rhsIndex];
start++;
rhsIndex++;
}
result.arr[start] = 0;
return result;
}
bool String::operator==(const String& rhs) const{
if (length() != rhs.length())
return false;
for (int i = 0; i < length(); ++i)
if (arr[i] != rhs.arr[i])
return false;
return true;
}
bool String::operator!=(const String& rhs) const{
if (*this == rhs)
return false;
return true;
}
bool String::operator<(const String& rhs) const{
int i = 0;
while (arr[i] != 0 && rhs.arr[i] != 0){
if ((arr[i] - rhs.arr[i]) < 0)
return true;
else if ((arr[i] - rhs.arr[i]) > 0)
return false;
i++;
}
if (length() < rhs.length())
return true;
return false;
}
bool String::operator>(const String& rhs) const{
if (*this == rhs)
return false;
if (*this < rhs)
return false;
return true;
}
bool String::operator<=(const String& rhs) const{
if (*this == rhs)
return true;
if (*this < rhs)
return true;
return false;
}
bool String::operator>=(const String& rhs) const{
if (*this == rhs)
return true;
if (*this < rhs)
return false;
return true;
}
//////////////////////////////free functions////////////////////////////////
////////////////////////////////////////////////////////////////////////////
///////////////they use the public functions of the String class////////////
String operator+(const char lhs[], const String& rhs){
String lhsString(lhs);
String result = lhsString + rhs;
return result;
}
String operator+(const char lhs, const String& rhs){
String lhsString(lhs);
String result = lhsString + rhs;
return result;
}
bool operator==(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString == rhs;
}
bool operator==(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString == rhs;
}
bool operator!=(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString != rhs;
}
bool operator!=(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString != rhs;
}
bool operator<(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString < rhs;
}
bool operator<(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString < rhs;
}
bool operator>(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString > rhs;
}
bool operator>(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString > rhs;
}
bool operator<=(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString <= rhs;
}
bool operator<=(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString <= rhs;
}
bool operator>=(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString >= rhs;
}
bool operator>=(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString >= rhs;
}
I've added some to the code for debugging purposes. The 6 never appears.
String postfix(String infix){
std::vector<String> vec;
vec = infix.split(' ');
Stack<String> tmp;
String right, left, op;
int i = 0;
while (vec[i] != ';'){
std::cout << 1 << std::endl;
if (vec[i] == ')'){
right = tmp.pop();
op = tmp.pop();
left = tmp.pop();
std::cout << 2 << std::endl;
tmp.push(left + ' ' + right + ' ' + op);
std::cout << 3 << std::endl;
}else{
if (vec[i] != '(' && vec[i] != ' ')
std::cout << 4 << std::endl;
tmp.push(vec[i]);
std::cout << 5 << std::endl;
}
++i;
}
std::cout << 6 << std::endl;
String postfix = tmp.pop();
return postfix;
}
Output is
-bash-4.1$ make tests
g++ -g -Wall -W -Wunused -Wuninitialized -Wshadow -iquote . -iquote ../string -c test_data3.cpp
g++ -g -Wall -W -Wunused -Wuninitialized -Wshadow string.o test_data3.o -o test_data3
./test_intStack
Everything looks good. Done testing an int Stack.
./test_stringStack
Everything looks good. Done testing a String Stack.
./test_data3
( AX + ( B * C ) ) ;
1
5
1
4
5
1
4
5
1
5
1
4
5
1
4
5
1
4
5
1
2
3
1
2
3
1
4
5
make: * [tests] Segmentation fault (core dumped)
rm test_data3.o
You almost certainly want to start by isolating the problem.
To do that, I'd start by doing a bit of rewriting to use your own code for the postfix conversion itself, but use std::string and std::stack for the string and stack type respectively.
If that makes the problem disappear, switch one (but not both) back to use your class. If it still works, switch the other to use your class.
Chances are very good that this will fairly quickly tell you whether the problem is in your postfix-conversion, your Stack, or your String. Once you've figured that out, I'd probably work at writing some decent unit tests for the component in question.
You could just debug it in context instead, but chances are pretty fair (at least in my experience) that doing so will often leave a number of similar problems, so the next time you try to use it, you'll run into similar problems under slightly different circumstances. By working at it more systematically you can eliminate entire classes of bugs instead of removing them one at a time.

Overloading insertion and extraction operators for strings

I would like to implement both of these functions so that I would be able to input and output objects of my class. I have gotten the >> operator to work but not so much <<.
Here is my code in my .h file:
class MyString
{
public:
MyString();
MyString(char *message);
~MyString();
void Print();
void Copy(MyString& rhs);
int Length();
MyString& operator()(const int index, const char b);
char& operator()(const int i);
MyString& operator=(const MyString& rhs);
bool operator==(const MyString& other) const;
bool operator!=(const MyString& other) const;
const MyString operator+(const MyString& rhs) const;
MyString& operator+=(const MyString& rhs);
private:
char *String;
int Size;
};
istream& operator>>(istream& input, MyString& rhs);
ostream& operator<<(ostream& output, const MyString& rhs);
Here is my code for the two functions in my .cpp file:
MyString::MyString()
{
char temp[] = "Hello World";
int counter(0);
while(temp[counter] != '\0') {
counter++;
}
Size = counter;
String = new char [Size];
for(int i=0; i < Size; i++)
String[i] = temp[i];
}
MyString::MyString(char *message)
{
int counter(0);
while(message[counter] != '\0') {
counter++;
}
Size = counter;
String = new char [Size];
for(int i=0; i < Size; i++)
String[i] = message[i];
}
MyString::~MyString()
{
delete [] String;
}
int MyString::Length()
{
int counter(0);
while(String[counter] != '\0')
{
counter ++;
}
return (counter);
}
const MyString MyString::operator+(const MyString& rhs) const
{
char* tmp = new char[Size + rhs.Size +1];
for(int i = 0; i < Size; i++)
{
tmp[i] = String[i];
}
for(int i = 0; i < rhs.Size+1; i++)
{
tmp[i+Size] = rhs.String[i];
}
const MyString MyString::operator+(const MyString& rhs) const
{
char* tmp = new char[Size + rhs.Size +1];
for(int i = 0; i < Size; i++)
{
tmp[i] = String[i];
}
for(int i = 0; i < rhs.Size+1; i++)
{
tmp[i+Size] = rhs.String[i];
}
MyString result;
delete [] result.String;
result.String = tmp;
result.Size = Size+rhs.Size;
return result;
}
MyString& MyString::operator()(const int index, const char b)
{
if(String[index] == '\0')
{
exit(1);
}
else
{
String[index] = b;
}
}
MyString& MyString::operator=(const MyString& rhs)
{
if(this != &rhs)
{
delete [] String;
String = new char[rhs.Size];
Size = rhs.Size;
for(int i = 0; i < rhs.Size+1 ; i++)
{
String[i] = rhs.String[i];
}
}
return *this;
}
void MyString::Copy(MyString& rhs)
{
delete [] String;
Size = rhs.Size;
String = new char[rhs.Size];
String = rhs.String;
}
MyString& MyString::operator+=(const MyString& rhs)
{
char* tmp = new char[Size + rhs.Size + 1];
for(int i = 0; i < Size; i++)
{
tmp[i] = String[i];
}
for(int i = 0; i <rhs.Size+1; i++)
{
tmp[i+Size] = rhs.String[i];
}
delete [] String;
String = tmp;
Size += rhs.Size;
return *this;
}
bool MyString::operator!=(const MyString& other) const
{
return !(*this == other);
}
bool MyString::operator==(const MyString& other)const
{
if(other.Size == this->Size)
{
for(int i = 0; i < this->Size+1; i++)
{
if(&other == this)
return true;
}
}
else
return false;
}
char& MyString::operator()(const int i)
{
if( String[i] == '\0')
{
exit(1);
}
else
{
return String[i];
}
}
void MyString::Print()
{
for(int i=0; i < Size; i++)
cout << String[i];
cout << endl;
}
istream& operator>>(istream& input, MyString& rhs)
{
char* temp;
int size(256);
temp = new char[size];
input.getline(temp,size);
rhs = MyString(temp);
delete [] temp;
return input;
}
ostream& operator<<(ostream& output, const MyString& rhs)
{
char* p;
int size(256);
p = new char[size];
output << rhs.MyString(p);
delete [] p;
return output;
}
Here is how it is called in the main.cpp file:
cin >> SearchString >> TargetString; // Test of cascaded string-extraction operator<</*
if(SearchString.Find(ConstString) != -1) {
cout << ConstString << " is not in " << SearchString << endl; }
else {
cout << ConstString << " is in " << SearchString << endl;
cout << "Details of the hit: " << endl;
cout << "Starting poisition of the hit: " << SearchString.Find(ConstString) << endl;
cout << "The matching substring is: " << SearchString.Substring(SearchString.Find(ConstString), ConstString.length()); }
Again, the cin>> operator works perfectly but please help me to figure out how to output the string.
Not really sure what you are asking. The implementation depends on how you want to output the string.
For some raw output the code will most likely look like this:
output << rhs.get_data();