Я работаю с Rad Studio, построителем C++. Размер AnsiString составляет ~ 2 ^ 31 символа. Как мне проверить длину?
if (ExportFileName.Length() > ??? )
{
ExportFileName. ???
}
m_ActionsHelper.LastPdfFile = ExportFileName;
Что касается вашей проблемы, то значение, которое вы ищете, - 0x7ffffffful
. Однако, если длина превысит это значение, уже слишком поздно.
и как мне его обрезать? используя Удалить?
Как я сказал в своем комментарии, к тому времени уже слишком поздно, и вы уже превысили лимит. Если AnsiString
позволяет даже выйти за такой предел. Я по-прежнему настоятельно рекомендую вам рассмотреть другие варианты, прежде чем сохранять такие большие объемы в AnsiString
, но если вы настаиваете, я рекомендую вам изменить свой код, чтобы проверить длину перед добавлением в строку. Если текущая длина плюс длина строки, которую вы хотите добавить, слишком длинная, не добавляйте. Так что не нужно усекать.
Как вы для начала сохраняете больше символов MaxInt
(0x7FFFFFFF) в AnsiString
? Вы должны были получить ошибки памяти от RTL задолго до того, как AnsiString
достиг такого размера.
Как я вижу в Справка, оба параметра Delete
- это int
, максимальное значение которого намного ниже, чем 2^31
. Похоже, вам такая проверка не нужна.
В любом случае, если вы хотите получить целочисленную степень 2
, вы можете использовать оператор двоичного сдвига:
1ull << 31
Оператор двоичного сдвига манипулирует битами целого числа таким образом, что все биты сдвигаются в нужном направлении. Например,
Operation Bits Shifted bits 10-based
1 << 1 00000001 00000010 2
1 << 2 00000001 00000100 4
4 << 2 00000100 00010000 16
И так далее. Итак, 1ull << 31
- это 2^31
. ull
означает, что мы используем 64-битное число, потому что int
для него слишком мал.
Чтобы удалить лишний хвост с помощью Delete, это должно быть похоже на
ExportFileName.Delete(1 << 10, ExportFileName.Length());
или же
ExportFileName.SetLength(1 << 10);
И, наверное, вам не нужно заранее проверять длину. Просто Delete
или SetLength
. Если он уже удовлетворен, никаких действий выполняться не будет.
и чтобы обрезать строку, я должен использовать Delete?
Я не знаю этого фреймворка, но, как я вижу в справочнике, он должен быть похож на ExportFileName.Delete(1 << 31, ExportFileName.Length());
.
Но длина возвращает int, 1 << 31 не шестнадцатеричный?
@AlexandraTupu Нет. В C++ только литералы могут быть представлены в шестнадцатеричном формате.
строка такая же, не модифицируется
@AlexandraTupu Вы уверены, что до проверки было больше 2 ^ 31? В противном случае его не следует изменять.
Прохладный! На stackoverflow.com мы голосуем за или принимаем ответы, если считаем, что они были полезны.
1 << 31
равен 0x80000000, что больше, чем MaxInt
(0x7FFFFFFF). Delete()
принимает int
в качестве входных данных, значение 1 << 31
слишком велико для его обработки, и при передаче в качестве int
значение будет отрицательным. 1 << 30
- это 0x40000000, что меньше MaxInt
. Также обратите внимание, что 1-й параметр Delete()
- это индекс, отсчитываемый от 1, а 2-й параметр - это количество удаляемых символов. При удалении символов в конце строки вы также можете использовать SetLength()
вместо Delete()
.
Тип возврата AnsiString::Length
- int
, который имеет 32-разрядную подпись. Так что этот тест никогда не может быть успешным. Кроме того, функция SetLength
принимает в качестве параметра int
; передача ему 1ull << 31
вызывает поведение, определяемое реализацией (возможно, передача отрицательного значения)
@ M.M Думаю, я заметил это в посте. Не могли бы вы прочитать это?
Я переместил предупреждение о целочисленном переполнении в начало сообщения и исправил параметры Delete
и SetLength
, чтобы никого не смущать.
Для таких больших данных я бы сказал, что
AnsiString
не является подходящим контейнером. Если это данные из файла, рассмотрите возможность использования сопоставления памяти.