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 '\0')
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] = '\0';
}
string::string(char* source) {
if (source == nullptr) {
size = 1;
s = new char[size];
s[0] = '\0';
}
else {
size_t i = 0;
while (source[i] != '\0') { //To remove NULL/redundant elements of source array from istream assignment
i++;
}
size = i + 1;
s = new char[size];
s[size - 1] = '\0';
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] = '\0';
}
else {
size = strlen(source) + 1;
s = new char[size];
s[size - 1] = '\0';
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] = '\0';
}
else {
size = strlen(t) + 1;
s = new char[size];
s[size - 1] = '\0';
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] != '\0' && 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 '\0' character
}
I do not know what makes the difference between to cases. Maybe I have missed some necessary commands.
Edit: I have known assigning c after input a and b will solve the problem. However, I don't want to do so because I want to separate assigning part and complying part in order to have neat code. Is there any way to fix error without assigning c after input a and b?