C样式字符串未更新为=运算符-C++; 最近我在玩创建自己的C++类的概念,这些类代表通用数据(如字符串、数字和数组)。

C样式字符串未更新为=运算符-C++; 最近我在玩创建自己的C++类的概念,这些类代表通用数据(如字符串、数字和数组)。,c++,C++,到目前为止,我在这方面取得了很好的进展(如图所示:) 除了一个故障。就我的一生而言,我无法理解为什么下面的代码在创建具有可变参数量的Stringclass对象时会出错 #include <iostream> #include <sstream> #include <string.h> // Make a new C-style string (or stringify a value). char* stringify(char character) {

到目前为止,我在这方面取得了很好的进展(如图所示:)

除了一个故障。就我的一生而言,我无法理解为什么下面的代码在创建具有可变参数量的
String
class对象时会出错

#include <iostream>
#include <sstream>
#include <string.h>

// Make a new C-style string (or stringify a value).
char* stringify(char character) {
    std::string stream = static_cast<std::ostringstream*>(&(std::ostringstream() << character)) -> str();
    char* string = new char[stream.size() + 1];

    strcpy(string, stream.c_str());
    return string;
}
template <typename data> char* stringify(data string) { return strdup(std::string(string).c_str()); }

char* globalString = stringify("");

class String {
    public:
        char* value = stringify("");

        String() {}
        template <typename data>
        String(data value) {
            strcat(globalString, value);
            this -> value = stringify(globalString);
            globalString = stringify("");
        }
        template <typename data, typename... argumentsData>
        String(data value, argumentsData... values) {
            strcat(globalString, stringify(value));
            String(values...);
        }
};

int main(int argc, char* argv[]) {
    std::cout << "String [1]: '" << String("Hello, World!").value << '\'' << std::endl;
    // -> String [1]: 'Hello, World!'

    std::cout << "String [3]: '" << String("Hello,", ' ', "World!").value << '\'';
    // -> String [3]: ''

    return 0;
}
// Works fine
String("Hello, World!").value // -> Hello, World!

// Needs fixing
String("Hello,", ' ', "World!").value // -> ...

我知道这可能不是一个提出这种性质问题的平台,但一点帮助会大有帮助。感谢阅读。

globalString
是指向
stringify(“”)返回值的
char*

stringify(“”)
返回
strdup(std::string(string).c_str())
strdup
返回动态分配的字符串,该字符串具有其参数的长度(以及相同的内容)

此处,
仅包含
\0
,因此从
strdup
返回的C字符串的长度将仅为
1


然后尝试调用
strcat(destination,source)
,将
globalString
作为目标,但是
globalString
不够大,无法容纳

strcat
说:

如果目标数组不大,则行为未定义 足够src和dest的内容以及终止null 性格如果字符串重叠,则行为未定义。这个 如果dest或src不是指向 以null结尾的字节字符串

因此,您的两个测试用例都是UB。即使是第一次测试,似乎工作得很好



std::string
为您处理所有这些。如果你因为教授给你的任何(愚蠢的)原因而不被允许使用它,那么在调用strcat之前,一定要为globalString分配足够的空间,C-string是一种狡猾的野兽。

globalString
是指向
stringify(“”)返回值的
char*

stringify(“”)
返回
strdup(std::string(string).c_str())
strdup
返回动态分配的字符串,该字符串具有其参数的长度(以及相同的内容)

此处,
仅包含
\0
,因此从
strdup
返回的C字符串的长度将仅为
1


然后尝试调用
strcat(destination,source)
,将
globalString
作为目标,但是
globalString
不够大,无法容纳

strcat
说:

如果目标数组不大,则行为未定义 足够src和dest的内容以及终止null 性格如果字符串重叠,则行为未定义。这个 如果dest或src不是指向 以null结尾的字节字符串

因此,您的两个测试用例都是UB。即使是第一次测试,似乎工作得很好



std::string
为您处理所有这些。如果你因为教授给你的任何(愚蠢的)理由而不被允许使用它,那么在调用strcat之前,请确保为
globalString
分配足够的空间,C字符串是很棘手的。。我想我现在开始明白了。老实说,我将使用
std::string
来重新实现代码,因为它处理的细节非常挑剔。但是谢谢你通过我解释。。我想我现在开始明白了。老实说,我将使用
std::string
来重新实现代码,因为它处理的细节非常挑剔。但是谢谢你解释清楚。