Возврат массива нулевых символов с перезаписью Java String.toUpperCase ()

Я изначально программист на Java, и мне очень нравится синтаксис, особенно в отношении объекта String. В C ++ я попытался воссоздать toUpperCase() метод, который есть в Java. Единственная проблема заключается в том, что он всегда возвращает объект String, который имеет пустой массив символов / NULL.

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