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
来重新实现代码,因为它处理的细节非常挑剔。但是谢谢你解释清楚。