User input has a different output from assigned-value input though both of them have the same value

  array-difference, c++, oop, output, string

I am building a custom string class. However, the user inputs give different output from the assigned-value one. For example:
With the assigned values:

    #include"custom_string.h"
    int main() {
        string a = "Hello";
        string b = "World";
        string c = a + b;
        std::cout << "C string is: " << c << std::endl;
        std::cout << "Length of C string is: " << c.length() << std::endl;
        system("pause");
        return 1;
}

Then the output would be:

C string is: HelloWorld

Length of C string is: 10

In user input case:

    #include"custom_string.h"
        int main() {
            string a;
            string b;
            string c = a + b;
            std::cout << "Input a string: " << std::endl;
            std::cin >> a;
            std::cout << "Input b string: " << std::endl;
            std::cin >> b;
            std::cout << "C string is: " << c << std::endl;
            std::cout << "Length of C string is: " << c.length() << std::endl;
            system("pause");
            return 0;
}

Then the output would be:

Input a string:

Hello

Input b string:

World

C string is:

Length of C string is: 0

Here is the code source of "custom_string.h":

 #ifndef _STRING
        #define _STRING
        #include<iostream>
        #include<cstring>
        #define MAX 99999
        class string {
        private:
            char* s = nullptr; //Member of custom string
            unsigned int size = 0; // length of string (including '{$content}')
        public:
            string();
            ~string() { delete s; };
            string(char* );
            string(const char* );
            string(const string&);
            friend std::istream& operator >> (std::istream&, string&);
            friend std::ostream& operator << (std::ostream&, string&);
            friend string operator +(string, string);
            string& operator = (const string&);
            string& operator = (const char&);
            unsigned int length();
            char* output() const{
                return s;
            }
        };
        #endif

    string::string() :s{ nullptr } {
        size = 1;
        s = new char[size];
        s[0] = '{$content}';
    }
    string::string(char* source) {
        if (source == nullptr) {
            size = 1;
            s = new char[size];
            s[0] = '{$content}';
        }
        else {
            size_t i = 0;
            while (source[i] != '{$content}') { //To remove NULL/redundant elements of source array from istream assignment
                i++;
            }
            size = i + 1;
            s = new char[size];
            s[size - 1] = '{$content}';
            for (size_t k = 0; k < size - 1; k++) {
                s[k] = source[k];
            }
        }
    }
    string::string(const char* source) {
        if (source == nullptr) {
            size = 1;
            s = new char[size];
            s[0] = '{$content}';
        }
        else {
            size = strlen(source) + 1;
            s = new char[size];
            s[size - 1] = '{$content}';
            for (size_t k = 0; k < (size - 1); k++) {
                s[k] = source[k];
            }
        }
    }
    string::string(const string& t) {
        size = t.size;
        s = new char[size];
        for (size_t k = 0; k < size; k++) {
            s[k] = t.s[k];
        }
    }
    string& string::operator=(const string& source) {
        if (source.s == s) {
            return *this;
        }
        else {
            delete[] s;
            size = source.size;
            s = new char[size];
            for (size_t k = 0; k < size; k++) {
                s[k] = source.s[k];
            }
            return *this;
        }
    }
    string& string::operator=(const char&source) {
        const char* t = &source;
        if (t == nullptr) {
            size = 1;
            s = new char[size];
            s[0] = '{$content}';
        }
        else {
            size = strlen(t) + 1;
            s = new char[size];
            s[size - 1] = '{$content}';
            for (size_t k = 0; k < (size - 1); k++) {
                s[k] = t[k];
            }
        }
        return* this;
    }
    string operator +(string a, string b) {
        if (a.s == nullptr ) { return b; }
        if (b.s == nullptr ) { return a; }
        string t;
        size_t k = 0;
        size_t l = 0;
        t.size = (a.size + b.size) - 1;
        t.s = new char[t.size];
        while (a.s[k] != '{$content}' && k < a.size && k < t.size) {
            t.s[k] = a.s[k];
            k++;
        }
        while (k < t.size && l < b.size) {
            t.s[k] = b.s[l];
            k++;
            l++;
        }
        return t;
    }
    std::istream& operator >> (std::istream& is, string& source) {
        char* t = new char[MAX];
        is >> t;
        source = string{ t };
        delete[] t;
        return is;
    }
    
    std::ostream& operator << (std::ostream& os, string& source) {
        os << source.output();
        return os;
    }
unsigned int string::length() {
    return (size - 1); //Ignore the '{$content}' character
}

I do not know what makes the difference between to cases. Maybe I have missed some necessary commands.

Source: Windows Questions C++

LEAVE A COMMENT