Връщане на null char масив с пренаписване на String.toUpperCase() на Java

Първоначално съм Java програмист и много обичам синтаксиса, особено по отношение на обекта String. С C++ се опитах да пресъздам метода toUpperCase(), който Java има. Единственият проблем е, че винаги връща 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);
}

person Mackenzie    schedule 18.03.2014    source източник
comment
Ще бъде по-разумно да използвате нещо от тук: stackoverflow.com/questions/735204/ и std::string като цяло. Тази функция изпуска памет при всяко извикване. Също така прочетете малко документация за toupper.   -  person chris    schedule 18.03.2014
comment
Използвайте std::string за низове   -  person D'artanian    schedule 18.03.2014
comment
Също така: В Java и C# използвате new много, в C++ трябва да го избягвате, когато е възможно (без GC).   -  person crashmstr    schedule 18.03.2014
comment
Като общо правило не се опитвайте да пресъздавате API на Java клас в C++ класове (те са оптимизирани за Java, така че това, което получавате в крайна сметка, обикновено е вариант на Мога да напиша C код във всяка езикова тема). За да конвертирате C++ низ в главни букви, вижте този отговор.   -  person utnapistim    schedule 18.03.2014
comment
Друга бележка, спрете да злоупотребявате с указатели (т.е. трябва да напишете return String(a); вместо 'return *new String(a);' и да използвате интелигентен указател на a или още по-добре std::vector); Освен това спрете да пишете this->. Излишно е. Също така обмислете използването на std::fill вместо memset и std::copy вместо memcpy.   -  person utnapistim    schedule 18.03.2014
comment
@KonradRudolph, редактира коментара ми (благодаря).   -  person utnapistim    schedule 18.03.2014


Отговори (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);
});
person Zac Howland    schedule 18.03.2014
comment
или просто std::transform(myCopy.begin(), myCopy.end(), myCopy.begin(), std::toupper), ако нямате нужда от локална чувствителност. - person japreiss; 18.03.2014
comment
@japreiss, Това не винаги ще работи толкова добре, въпреки че отговорът също няма да го направи, ако char е подписано и има отрицателни стойности. Можете да проверите връзката, която коментирах, за повече дискусии относно този метод. - person chris; 18.03.2014
comment
@japreiss Бих казал, че неизползването на локал винаги се поврежда при работа с текст – как можете да изключите необходимостта от използване на локали? От друга страна, локалите в C++ така или иначе са повредени (т.е. горното прави грешното нещо за немския текст „Maß“, независимо от локала). - person Konrad Rudolph; 18.03.2014
comment
@japreiss Основният проблем с използването на версията, която не приема локал, е, че това е пренасянето от стандартната библиотека C, която взема и връща int с много специфични критерии. Ако char е подписано на дадена платформа, извикването на int std::toupper(int) може да доведе до недефинирано поведение. - person Zac Howland; 18.03.2014
comment
Благодаря, предполагам, че неправилният ми коментар се оказа добър опит :) - person japreiss; 18.03.2014