I've been working on a C++ program, I've made the logic but I'm unable to execute it. The question is:
Task: Write a program, using functions only, with the following features.
Program reads paragraph(s) from the file and stores in a string.
Then program counts the occurrence of each word in the paragraph(s) and stores all words with their number of occurrences.
If that word has appeared more than one time in whole string, it should store the word only once along its total occurrences.
The output described in above (in part 3) must be stored in a new file.
Sample input:
is the is and the is and the and is and only that is
Sample output:
is 5
the 3
and 4
only 1
that 1
I'll cut short to Occurrence program that I've written,
My logic is to store token into character array and then compare that array with main character array and do the increment:
void occurances() {
char* string = getInputFromFile();
char separators[] = ",.\n\t ";
char* token;
char* nextToken;
char* temp[100];
token = strtok_s(string, separators, &nextToken);
cout << temp;
int counter = 0;
int i = 0;
while ((token != NULL)) {
temp[i] = token;
i++;
for (int i = 0; i < strlen(string); i++) {
for (int j = 0; j < 100; j++) {
if ((strcmp(token, *temp)) == 0) {
counter++;
}
}
cout << temp << " : " << counter << endl;
}
if (token != NULL) {
token = strtok_s(NULL, separators, &nextToken);
}
}
}
This code is preposterous I know that, But please anyone be kind enough to give me a clue, actually I'm new to C++ . Thank you
If you store token into array this array should grow dynamically because the number of tokens is not known at the beginning. And according to the task description, you cannot use C++ standard containers, so, it is necessary to implement dynamic array manually, for example:
#include <iostream>
std::size_t increase_capacity_value(std::size_t capacity) {
if (capacity == 0) {
return 1;
}
else if (capacity < (SIZE_MAX / 2)) {
return capacity * 2;
}
return SIZE_MAX;
}
bool increase_array_capacity(char**& tokens_array, std::size_t*& tokens_count, std::size_t& capacity) {
const std::size_t new_capacity = increase_capacity_value(capacity);
if (new_capacity <= capacity) {
return false;
}
const std::size_t tokens_array_byte_size = new_capacity * sizeof(char*);
char** const new_tokens_array = static_cast<char**>(std::realloc(tokens_array, tokens_array_byte_size));
if (new_tokens_array == nullptr) {
return false;
}
tokens_array = new_tokens_array;
const std::size_t tokens_count_byte_size = new_capacity * sizeof(std::size_t);
std::size_t* const new_tokens_count = static_cast<std::size_t*>(std::realloc(tokens_count, tokens_count_byte_size));
if (new_tokens_count == nullptr) {
return false;
}
tokens_count = new_tokens_count;
capacity = new_capacity;
return true;
}
bool add_token(char* token, char**& tokens_array, std::size_t*& tokens_count, std::size_t& array_size, std::size_t& array_capacity) {
if (array_size == array_capacity) {
if (!increase_array_capacity(tokens_array, tokens_count, array_capacity)) {
return false;
}
}
tokens_array[array_size] = token;
tokens_count[array_size] = 1;
++array_size;
return true;
}
std::size_t* get_token_count_storage(char* token, char** tokens_array, std::size_t* tokens_count, std::size_t array_size) {
for (std::size_t i = 0; i < array_size; ++i) {
if (std::strcmp(token, tokens_array[i]) == 0) {
return tokens_count + i;
}
}
return nullptr;
}
bool process_token(char* token, char**& tokens_array, std::size_t*& tokens_count, std::size_t& array_size, std::size_t& array_capacity) {
std::size_t* token_count_ptr = get_token_count_storage(token, tokens_array, tokens_count, array_size);
if (token_count_ptr == nullptr) {
if (!add_token(token, tokens_array, tokens_count, array_size, array_capacity)) {
return false;
}
}
else {
++(*token_count_ptr);
}
return true;
}
int main() {
char string[] = "is the is and the is and the and is and only that is";
char separators[] = ",.\n\t ";
std::size_t token_array_capacity = 0;
std::size_t token_array_size = 0;
char** tokens_array = nullptr;
std::size_t* tokens_count = nullptr;
char* current_token = std::strtok(string, separators);
while (current_token != nullptr) {
if (!process_token(current_token, tokens_array, tokens_count, token_array_size, token_array_capacity)) {
break;
}
current_token = std::strtok(nullptr, separators);
}
// print the report only if all tokens were processed
if (current_token == nullptr) {
for (std::size_t i = 0; i < token_array_size; ++i) {
std::cout << tokens_array[i] << " : " << tokens_count[i] << std::endl;
}
}
std::free(tokens_array);
std::free(tokens_count);
}
godbolt.org
okay what if i want to store any token once, in an array and then replace it with new word while deleting duplicates in character array
It is also possible solution. But in general case, it is also necessary to allocate the memory dynamically for the current token. Because the lengths of tokens are also not known at the beginning:
void replace_chars(char* str, const char* chars_to_replace) {
while (str && *str != '\0') {
str = std::strpbrk(str, chars_to_replace);
if (str == nullptr) {
break;
}
const std::size_t number_of_delimiters = std::strspn(str, chars_to_replace);
for (std::size_t i = 0; i < number_of_delimiters; ++i) {
str[i] = '\0';
}
str += number_of_delimiters;
}
}
bool keep_token(char*& token_storage, const char* new_token) {
if (new_token == nullptr) {
return false;
}
const std::size_t current_token_len = token_storage ? std::strlen(token_storage) : 0;
const std::size_t requried_token_len = std::strlen(new_token);
if (token_storage == nullptr || current_token_len < requried_token_len) {
token_storage =
static_cast<char*>(std::realloc(token_storage, (requried_token_len + 1) * sizeof(char)));
if (token_storage == nullptr) {
return false;
}
}
std::strcpy(token_storage, new_token);
return true;
}
std::size_t count_tokens_and_replace(char* str, std::size_t str_len, const char* token) {
std::size_t number_of_tokens = 0;
std::size_t i = 0;
while (i < str_len) {
while (str[i] == '\0') ++i;
if (std::strcmp(str + i, token) == 0) {
replace_chars(str + i, token);
++number_of_tokens;
}
i += std::strlen(str + i);
}
return number_of_tokens;
}
int main() {
char string[] = "is the is and the is and the and is and only that is";
char separators[] = ",.\n\t ";
const std::size_t string_len = std::strlen(string);
replace_chars(string, separators);
std::size_t i = 0;
char* token = nullptr;
while (true) {
while (i < string_len && string[i] == '\0') ++i;
if (i == string_len || !keep_token(token, string + i)) break;
std::cout << token << " : " << count_tokens_and_replace(string + i, string_len - i, token) << std::endl;
}
std::free(token);
}
godbolt.org
But if it is known that the token length cannot be greater than N, it is possible to use the static array of chars to keep the current token. And it will allow to remove dynamic memory allocation from the code.
Related
I am trying to make program that get infix to postfix but when I entered +- in the infix equation
the output should be +- but I find that the output is ++ and if infix is -+ the output is --
it have been a week since I started to solve that problem
#include <iostream>
#include <string>
using namespace std;
//classes
class arr
{
private:
char *items;
int size;
int length;
public:
//default constructor
arr()
{
items = new char[100];
size = 100;
length = 0;
}
//constructor with parameters
arr(int arraySize)
{
items = new char[arraySize];
size = arraySize;
length = 0;
}
//check if array is empty
bool is_empty()
{
return length == 0 ? true : false;
}
//check if array full
bool is_full()
{
return length >= size - 1 ? true : false;
}
//returns array length
int getLength()
{
return length;
}
//return array size
int getSize()
{
return size;
}
//get array address
char *getAddress()
{
return &items[0];
}
//fill number of items in array based on elementNum
void fill(int elementNum)
{
char ch;
cout << "Enter characters you want to add\n";
if (elementNum > size - 1)
{
cout << "can't use elements number largger than " << size - 1;
return;
}
for (int i = 0; i < elementNum; i++)
{
cin >> ch;
insert(i, ch);
}
}
//display all elements in the array
void display()
{
if (is_empty())
{
cout << "there are no data /n";
return;
}
cout << "Array items are :\n";
for (int i = 0; i < length; i++)
{
cout << items[i] << "\t";
}
cout << endl;
}
void append(char ch)
{
insert(length, ch);
}
void insert(int index, char newItem)
{
if (is_full() || length<index || length + 1 == size)
{
cout << "\nSorry array is full\ncan't append letter more\n";
return;
}
else {
for (int i = length; i >= index; i--)
{
items[i + 1] = items[i];
}
items[index] = newItem;
length++;
}
}
int search(char ch)
{
if (!is_empty())
for (int i = 1; i <= length; i++)
{
if (items[i] == ch)
return i;
}
return 0;
}
void del(int index)
{
if (is_empty() || length<index) {
cout << "sorry can't delete item which is doesn't exist";
return;
}
for (int i = index; i < length; i++)
{
items[i] = items[i + 1];
}
length--;
}
void changeSize(int newSize)
{
if (newSize <= length - 1)
{
cout << "can't change size because the new size is small";
return;
}
char *tempItems = new char[newSize];
size = newSize;
for (int i = 0; i < length; i++)
{
tempItems[i] = items[i];
}
items = tempItems;
tempItems = NULL;
}
//merge two arrays
void merge(arr a)
{
this->size = this->size + a.getSize();
for (int i = 0; i < a.getLength(); i++)
{
items[i + length] = a.getAddress()[i];
}
length = this->length + a.getLength();
}
};
class stackUsingArray {
private:
int top;
arr a;
public:
stackUsingArray()
{
top = -1;
}
stackUsingArray(int stackSize)
{
a.changeSize(stackSize);
top = -1;
}
bool is_empty()
{
return(top == -1);
}
bool is_full()
{
return(a.is_full());
}
void push(char ch)
{
top++;
a.append(ch);
}
char pop()
{
if (is_empty())
{
cout << "sorry the stack is empty";
}
else
return a.getAddress()[top--];
}
int peekTop() {
return top;
}
void display()
{
//first way of display
for (int i = top; i >= 0; i--)
{
cout << a.getAddress()[i];
}
//second way of display
//stackUsingArray c;
//char ch;
//for (int i = top; i >= 0; i--)
// c.push(this->pop());
//for (int i = c.peekTop(); i >= 0; i--)
//{
// ch=c.pop();
// this->push(ch);
// cout << ch;
//}
}
int search(char ch)
{
for (int i = top; i >= 0; i--)
{
if (a.getAddress()[i] == ch)
return i;
}
return -1;
}
char topDisplay()
{
return a.getAddress()[top];
}
};
class stackUsingLinkedList {};
//functions
string infixToPostfix(string infix);
short prec(char ch);
int main()
{
//infix and postfix
stackUsingArray c;
cout<<infixToPostfix("x+y-z");
system("pause");
return 0;
}
string infixToPostfix(string infix)
{
string postfix = "";
stackUsingArray sta;
char ch;
char test;
for (int i = 0; i < infix.length(); i++)
{
switch (prec(infix[i]))
{
case 0:
postfix.append(1, infix[i]);
break;
case 1:
sta.push(infix[i]);
break;
//case 2:
// ch = sta.pop();
// while (ch != '(')
// {
// postfix.append(1, ch);
// ch = sta.pop();
// }
// break;
case 3:
// if (sta.is_empty())
// {
// goto k270;
// }
// ch = sta.pop();
// while (prec(ch) > 3)
// {
// postfix.append(1, ch);
// if (sta.is_empty()) {
// //sta.push(infix[i]);
// goto k270;
// }
// ch = sta.pop();
// }
// sta.push(ch);
//k270:
// sta.push(infix[i]);
test = sta.topDisplay();
if (sta.is_empty())
{
sta.push(infix[i]);
test = sta.topDisplay();
}
else
{
ch = sta.pop();
test = sta.topDisplay();
if (prec(ch) >= 3)
{
postfix += ch;
}
sta.push(infix[i]);
}
}
}
while (!sta.is_empty())
{
postfix.append(1, sta.pop());
}
return postfix;
}
short prec(char ch)
{
if (ch == '(')
return 1;
if (ch == ')')
return 2;
if (ch == '+')
return 3;
if (ch == '-')
return 3;
if (ch == '*')
return 4;
if (ch == '/')
return 4;
return 0;
}
thanks to #IgorTandetnik I figured out that I should del last item from the array when I pop from stack
How should I go about finding the length of a char array in C++? I've tried two methods already, but they both have resulted in the wrong number of characters in the array. I've used strlen and the sizeof operator so far, to no avail.
void countOccurences(char *str, string word)
{
char *p;
string t = "true";
string f = "false";
vector<string> a;
p = strtok(str, " ");
while (p != NULL)
{
a.push_back(p);
p = strtok(NULL, " ");
}
int c = 0;
for (int i = 0; i < a.size(); i++)
{
if (word == a[i])
{
c++;
}
}
int length = sizeof(str); //This is where I'm having the problem
string result;
cout << length << "\n";
if (length % 2 != 0)
{
if (c % 2 == 0)
{
result = "False";
}
else
{
result = "True";
}
}
else
{
if (c % 2 == 0)
{
result = "True";
}
else
{
result = "False";
}
}
if (strlen(str) != 0)
{
cout << result;
}
}
int boolean()
{
char str[1000];
cin.getline(str, sizeof(str));
string word = "not";
countOccurences(str, word);
return 0;
}
sizeof(str) is wrong. It gives you the size of a pointer (str is a pointer), which is a fixed number, normally either 4 or 8 depending at your platform.
std::strlen(str) is correct, but strtok inserts a bunch of \0 into your array before you try to obtain the size. strlen will stop at the first \0, and give you the number of characters preceeding it.
Call strlen before strtok and save its return value to a variable.
Here you can find a modern c++ solution:
#include <iostream>
#include <string_view>
#include <string>
#include <type_traits>
template<typename String>
inline std::size_t StrLength(String&& str)
{
using PureString = std::remove_reference_t<std::remove_const_t<String>>;
if constexpr(std::is_same_v<char, PureString>){
return 1;
}
else
if constexpr(std::is_same_v<char*, PureString>){
return strlen(str);
}
else{
return str.length();
}
}
template<
typename String,
typename Lambda,
typename Delim = char
>
void ForEachWord(String&& str, Lambda&& lambda, Delim&& delim = ' ')
{
using PureStr = std::remove_reference_t<std::remove_reference_t<String>>;
using View = std::basic_string_view<typename PureStr::value_type>;
auto start = 0;
auto view = View(str);
while(true)
{
auto wordEndPos = view.find_first_of(delim, start);
auto word = view.substr(start, wordEndPos-start);
if (word.length() > 0){
lambda(word);
}
if (wordEndPos == PureStr::npos)
{
break;
}
start = wordEndPos + StrLength(delim);
}
}
int main() {
std::string text = "This is not a good sentence.";
auto cnt = 0;
ForEachWord(
text,
[&](auto word)
{
//some code for every word... like counting or printing
if (word == "not" ){
++cnt;
}
},
' '
);
std::cout << cnt << "\n";
}
The "end of a string" is the char '\0' check for that character to stop the search.
I am writing a BigBinaryString class in C++ which abstractly holds the large binary string and can perform operations like xor, and, left shift and right shift.
I have stored the binary string internally as a vector of unsigned longs, so each element in vector consumes 64-bits from the bitstring.
I have decided to use have four types of constructors:
BigBinaryString(const string bitstring) //for directly converting the bitstring to internal repr.
BigBinaryString() //initialize the binary string to 0.
BigBinaryString(const size_t num) //hold the binary for corresponding unsigned long.
BigBinaryString(const vector<size_t> vec) //Directly pass the internal repr to the constructor for it to copy.
So far I have implemented and, xor, equality and left shift operators.
However, I feel the left shift operator has a very high time complexity in which the way I have implemented it.
So, I need a few suggestions on how to speed up the left shift operator so that I can implement the right shift efficiently as well.
The code so far is as follows:
#define SIZE_UNSIGNED_LONG (sizeof(size_t) * 8)
class BigBinaryString {
private:
vector<size_t> num;
void reduce() {
while (*num.rbegin() == 0) {
num.pop_back();
}
if (num.size() == 0) {
num.push_back(0);
}
}
public:
BigBinaryString() { num.push_back(0); }
BigBinaryString(const size_t n) { num.push_back(n); }
BigBinaryString(const vector<size_t> vec) {
const size_t length = vec.size();
for (size_t i = 0; i < length; i++) {
num.push_back(vec.at(i));
}
reduce();
}
BigBinaryString operator&(const BigBinaryString& op) {
vector<size_t> vec;
size_t maxlen = max(num.size(), op.num.size());
size_t minlen = min(num.size(), op.num.size());
const size_t zero = 0;
for (size_t i = 0; i < minlen; i++) {
vec.push_back(num.at(i) & op.num.at(i));
}
return BigBinaryString(vec);
}
BigBinaryString(const string bitstring) {
string temp = bitstring;
size_t dec = 0;
while (temp.length() != 0) {
if (temp.length() > SIZE_UNSIGNED_LONG) {
dec = stoul(temp.substr(temp.length() - SIZE_UNSIGNED_LONG,
SIZE_UNSIGNED_LONG),
nullptr, 2);
temp = temp.substr(0, temp.length() - SIZE_UNSIGNED_LONG);
} else {
dec = stoul(temp, nullptr, 2);
temp = "";
}
num.push_back(dec);
}
reduce();
}
BigBinaryString operator^(const BigBinaryString& op) {
vector<size_t> vec;
size_t maxlen = max(num.size(), op.num.size());
size_t minlen = min(num.size(), op.num.size());
for (size_t i = 0; i < maxlen; i++) {
if (i < minlen) {
vec.push_back(num.at(i) ^ op.num.at(i));
} else if (maxlen == num.size()) {
vec.push_back(num.at(i));
} else if (maxlen == op.num.size()) {
vec.push_back(op.num.at(i));
}
}
return BigBinaryString(vec);
}
bool operator==(const BigBinaryString& op) {
if (num.size() != op.num.size()) {
return false;
}
size_t length = num.size();
for (size_t i = 0; i < length; i++) {
if (num.at(i) != op.num.at(i)) {
return false;
}
}
return true;
}
bool operator==(const size_t n) {
BigBinaryString op(n);
if (num.size() != op.num.size()) {
return false;
}
size_t length = num.size();
for (size_t i = 0; i < length; i++) {
if (num.at(i) != op.num.at(i)) {
return false;
}
}
return true;
}
bool operator!=(const BigBinaryString& op) { return not(*this == op); }
bool operator!=(const size_t op) { return not(*this == op); }
BigBinaryString operator<<(size_t shift) {
string bitstring = this->to_string();
bitstring.append(shift, '0');
return BigBinaryString(bitstring);
}
string to_string() {
string suffix = "";
string retval = "";
string prefix = "";
size_t n = 0;
for (auto i = num.rbegin(); i != num.rend(); i++) {
n = *i;
prefix.clear();
suffix.clear();
while (n != 0) {
suffix = (n % 2 == 0 ? "0" : "1") + suffix;
n /= 2;
}
if (i != num.rbegin()) {
prefix.append(SIZE_UNSIGNED_LONG - suffix.size(), '0');
}
prefix = prefix + suffix;
if (prefix.size() == SIZE_UNSIGNED_LONG) {
retval += prefix;
} else if (i == num.rbegin()) {
retval += prefix;
} else if (i != num.rbegin()) {
throw invalid_argument("prefix+suffix error");
}
}
return retval;
}
};
Any help will be appreciated!
I have a function that takes a user entered string and splits it into individual words using a dynamically allocated two-dimensional array. The words are separated by delimiters used as indicators of where one word ends and another begins.
Here is my code:
int countWords(const char * sentence, char * delims)
{
int wordsInArray = 0;
int count = 0;
while(*(sentence + count) != '\0')
{
if(*(sentence + count) == *delims && *(sentence + count + 1) != *delims)
{
wordsInArray++;
}
if(*(sentence + count + 1) == '\0')
{
wordsInArray++;
}
count++;
}
return wordsInArray;
}
int getLength(const char * sentence)
{
const char *p = sentence;
while(*p != '\0')
{
p++;
}
return p-sentence;
}
char ** getWords(const char * sentence, int & wordcount)
{
char delims[] = " .,\t?!";
int sentenceLength = getLength(sentence);
wordcount = countWords(sentence, delims);
char ** words;
words = new char *[wordcount];
int length = 0;
int count = 0;
for (int a = 0; a < sentenceLength; a++)
{
if(*(sentence + a) != *delims)
{
length++;
}
else if ((*(sentence + a) == *delims && *(sentence + a + 1) != *delims) || *(sentence + a) == '\0')
{
*(words + count) = new char[length+1];
for (int z = 0; z < length; z++)
{
*(*(words + count) + z) = *(sentence + z);
}
length = 0;
count++;
}
}
return words;
}
However, my countWords function is not properly counting the words in the string, and I do not know why.
Try something more like this:
int indexOf(const char * sequence, char ch) {
const char *p = sequence;
while (*p != '\0') {
if (*p == ch) {
return p - sequence;
}
}
return -1;
}
const char* findFirstOf(const char * sequence, const char *chars) {
const char *p = sequence;
while (*p != '\0') {
if (indexOf(chars, *p) != -1) {
return p;
}
}
return NULL;
}
const char* findFirstNotOf(const char * sequence, const char *chars) {
const char *p = sequence;
while (*p != '\0') {
if (indexOf(chars, *p) == -1) {
return p;
}
}
return NULL;
}
int countWords(const char * sequence, char * delims) {
int count = 0;
const char *p = sequence;
do {
p = findFirstNotOf(p, delims);
if (p == NULL) break;
++count;
p = findFirstOf(p, delims);
}
while (p != NULL);
return count;
}
int getLength(const char * sequence) {
const char *p = sequence;
while (*p != '\0') {
++p;
}
return p-sequence;
}
char* dupString(const char * sequence, int length = -1) {
if (length == -1) {
length = getLength(sequence);
}
char *result = new char[length+1];
for (int i = 0; i < length; ++i) {
result[i] = sequence[i];
}
result[length] = '\0';
return result;
}
char** getWords(const char * sequence, int & wordcount) {
const char delims[] = " .,\t?!";
int count = countWords(sequence, delims);
char ** words = new char *[count];
if (count > 0) {
count = 0;
const char *p = sequence;
do {
p = findFirstNotOf(p, delims);
if (p == NULL) break;
const char *q = findFirstOf(p, delims);
if (q == NULL) {
words[count++] = dupString(p);
break;
}
words[count++] = dupString(p, q-p);
p = ++q;
}
while (true);
}
wordcount = count;
return words;
}
That being said, the fact you are using new[] means you are using C++, so you should be using the STL to make life easier:
#include <string>
#include <vector>
std::vector<std::string> getWords(const std::string & sequence) {
const char delims[] = " .,\t?!";
std::vector<std::string> words;
std::string::size_type i = 0;
do {
i = sequence.find_first_not_of(delims, i);
if (i == std::string::npos) break;
std::string::size_type j = sequence.find_first_of(delims, i);
if (j == std::string::npos) {
words.push_back(sequence.substr(i));
break;
}
words.push_back(sequence.substr(i, j-i));
i = ++j;
}
while (true);
return words;
}
I am implementing my version of the basic String class, however I am running into an issue that I have never seen before and have no idea how to properly debug. My code is pasted below. All functions have their header counterparts. My test is simply creating one object using the convert constructor.
A4String obj1("this");
My problem is I get an Access violation reading location exception thrown. My research has indicated that I may be trying to access memory outside of Visual Studio's allotment. I'm having trouble finding where this pointer error exists though. I have placed breakpoints through every step of the convert constructor and subsequent function calls within however my program doesn't throw the exception until it returns to main, seemingly after my program has executed completely.
#include "A4String.h"
A4String::A4String() {
data = new char[5];
data[0] = '\0';
capacity = 5;
}
A4String::~A4String() {
if (capacity != 0)
delete[] data;
}
//Copy Constructor
A4String::A4String(const A4String &right) {
cout << "copy" << endl;
data = new char[right.capacity + 1];
strcpy(data, right.data, capacity);
capacity = right.capacity;
}
//Convert Constructor
A4String::A4String(const char *sptr) {
cout << "convert" << endl;
capacity = (strlen(sptr)) + 1;
data = new char[capacity + 1];
strcpy(sptr, data, capacity);
}
//Assignment
A4String& A4String::operator = (const A4String & right) {
//if (capacity != 0) delete[] data;
data = new char[right.capacity + 1];
strcpy(data, right.data, capacity);
capacity = right.capacity;
return *this;
}
//Equivalence
bool A4String::operator == (const A4String &right) const {
return (strcmp(data, right.data)) == 0;
}
int A4String::length() const {
return capacity;
}
void A4String::addChar(char) {
//Not implemented yet
}
string A4String::toString() {
string str = "";
int i = 0;
while (data[i] != '\0') {
str += data[i];
i++;
}
return str;
}
void A4String::strcpy(const char *source, char* destination, int size)
{
for (int i = 0; i < 20; i++)
destination[i] = '\0';
int index = 0;
while (source[index] != '\0')
{
destination[index] = source[index];
index++;
}
destination[index] = '\0';
}
int A4String::strcmp(char *str1, char *str2)
{
if (*str1 < *str2)
return -1;
if (*str1 > *str2)
return 1;
if (*str1 == '\0')
return 0;
return strcmp(str1 + 1, str2 + 1);
return 0;
}
int A4String::strlen( char *s)
{
char *start;
start = s;
while (*s != 0)
{
++s;
}
return s - start;
}
The problem is your A4String::strcpy, the line
for (int i = 0; i < 20; i++)
destination[i] = '\0';
The destination has less than 20 characters, so it crashes.
Use of the hard code number 20 in the A4String::strcpy is not right. I suggest changing it to size.
void A4String::strcpy(const char *source, char* destination, int size)
{
// for (int i = 0; i < 20; i++)
for (int i = 0; i < size; i++)
destination[i] = '\0';
int index = 0;
// Add an additional check here also.
// while (source[index] != '\0' )
while (source[index] != '\0' && index < size)
{
destination[index] = source[index];
index++;
}
destination[index] = '\0';
}
Disclaimer Fixing the above function may not fix your crashing problem even though the use of 20 is most likely crashing your program. In other words, there might be other problems in your code too.