通过重写 Java 的 String.toUpperCase() 返回空字符数组 [重复]
Posted
技术标签:
【中文标题】通过重写 Java 的 String.toUpperCase() 返回空字符数组 [重复]【英文标题】:Returning null char array with rewriting Java's String.toUpperCase() [duplicate] 【发布时间】:2014-03-18 13:29:47 【问题描述】:我最初是一名 Java 程序员,我非常喜欢语法,尤其是关于 String
对象。使用 C++,我尝试重新创建 Java 拥有的 toUpperCase()
方法。唯一的问题是它总是返回一个 String
具有空/NULL char 数组的对象。
String String::toUpperCase()
char *a = new char[this->length + 1];
memset(a, 0, this->capacity + 1);
memcpy(a, this->characters, this->length);
for (int i = 0; i < strlen(this->characters); i++)
toupper(a[i]);
return *new String(a);
【问题讨论】:
一般来说,使用这里的东西会更明智:***.com/questions/735204/… 和std::string
。每次调用此函数时都会泄漏内存。另外,请阅读toupper
的一些文档。
对字符串使用 std::string
另外:在 Java 和 C# 中,您经常使用 new
,在 C++ 中,您应该尽可能避免使用它(无 GC)。
作为一般规则,不要尝试在 C++ 类中重新创建 java 类 API(它们针对 Java 进行了优化,所以你最终得到的往往是“我可以编写 C 代码”的变体任何语言”主题)。要将 C++ 字符串转换为大写,请参阅this answer。
另一方面,停止滥用指针(即你应该写return String(a);
而不是'return *new String(a);'并在a
上使用智能指针,或者更好的是,a std::vector
);另外,停止写this->
。这是不必要的。还可以考虑使用std::fill
代替memset
和std::copy
代替memcpy
。
【参考方案1】:
您的尝试存在一些记忆问题,以及逻辑问题。您只需要返回一个字符为大写的字符串副本:
std::string str = "My Original string";
std::string myCopy(str);
std::locale loc;
std::transform(myCopy.begin(), myCopy.end(), myCopy.begin(), [&](char c)
return std::toupper(c, loc);
);
【讨论】:
如果您不需要区域设置敏感度,则只需std::transform(myCopy.begin(), myCopy.end(), myCopy.begin(), std::toupper)
。
@japreiss,这并不总是那么好,尽管如果char
被签名并且有负值,答案也不会。您可以查看我评论的链接以获取有关此方法的更多讨论。
@japreiss 我认为,在对文本进行操作时,不使用语言环境总是会被破坏——如何排除使用语言环境的需要?话又说回来,C++ 中的语言环境无论如何都被破坏了(即上面对德语文本“Maß”做了错误的事情,无论语言环境如何)。
@japreiss 使用不带语言环境的版本的主要问题是它是 C 标准库的继承,它采用并返回具有非常具体标准的 int
.如果char
在给定平台上签名,则对int std::toupper(int)
的调用可能会导致未定义的行为。
谢谢,我猜我的错误评论变成了一个很好的学习经验:)以上是关于通过重写 Java 的 String.toUpperCase() 返回空字符数组 [重复]的主要内容,如果未能解决你的问题,请参考以下文章