【问题标题】:User input has a different output from assigned-value input though both of them have the same value用户输入与赋值输入具有不同的输出,尽管它们都具有相同的值
【发布时间】:2021-08-02 22:38:42
【问题描述】:

我正在构建一个自定义字符串类。但是,用户输入给出的输出与分配的值不同。例如: 使用分配的值:

    #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;
}

那么输出将是:

C 字符串为:HelloWorld

C字符串长度为:10

在用户输入的情况下:

    #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;
}

那么输出将是:

输入一个字符串:

你好

输入b字符串:

世界

C 字符串是:

C字符串长度为:0

这里是“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
}

我不知道 to case 之间有什么区别。也许我错过了一些必要的命令。

编辑:我知道在输入 a 和 b 后分配 c 将解决问题。但是,我不想这样做,因为我想将分配部分和遵守部分分开,以便获得整洁的代码。有没有什么办法可以在输入 a 和 b 后不分配 c 来修复错误?

【问题讨论】:

  • 在第二种情况下,您分配c 之前 ab 有任何值。
  • 如何在 a 和 b 之后不指定 c 的情况下解决这个问题?你看,我想把分配部分和遵守部分分开,以便整洁
  • 执行初始化或分配给变量等操作的顺序很重要。如果您有两个语句A;B;,按照A; B; 的确切顺序,那么A 将在B 之前首先执行
  • 为什么不简单地定义变量c你读过输入之后?
  • @Eureka 理论上是可能的,但你不想那样做。您需要使您的string 类更像string_view - 使operator+ 返回对其添加的字符串的某种引用(而不是实际连接)并实现一些视图类来迭代这些引用。它绝对违反了最小惊讶规则。而不是一个字符串,谁是它的数据的所有者,你会得到一些奇怪的视图,它不拥有任何东西,只有对其他字符串的引用。

标签: c++ string oop output array-difference


【解决方案1】:
 #include"custom_string.h"
        int main() {
            string a;
            string b;
            std::cout << "Input a string: " << std::endl;
            std::cin >> a;
            std::cout << "Input b string: " << std::endl;
            std::cin >> b;
            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 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多