Усечь AnsiString

Я работаю с Rad Studio, построителем C++. Размер AnsiString составляет ~ 2 ^ 31 символа. Как мне проверить длину?

if (ExportFileName.Length() > ??? )
  {
    ExportFileName. ???
  }
  m_ActionsHelper.LastPdfFile = ExportFileName;

Для таких больших данных я бы сказал, что AnsiString не является подходящим контейнером. Если это данные из файла, рассмотрите возможность использования сопоставления памяти.

Some programmer dude 02.05.2018 14:18

Что касается вашей проблемы, то значение, которое вы ищете, - 0x7ffffffful. Однако, если длина превысит это значение, уже слишком поздно.

Some programmer dude 02.05.2018 14:19

и как мне его обрезать? используя Удалить?

Alexandra Tupu 02.05.2018 14:21

Как я сказал в своем комментарии, к тому времени уже слишком поздно, и вы уже превысили лимит. Если AnsiString позволяет даже выйти за такой предел. Я по-прежнему настоятельно рекомендую вам рассмотреть другие варианты, прежде чем сохранять такие большие объемы в AnsiString, но если вы настаиваете, я рекомендую вам изменить свой код, чтобы проверить длину перед добавлением в строку. Если текущая длина плюс длина строки, которую вы хотите добавить, слишком длинная, не добавляйте. Так что не нужно усекать.

Some programmer dude 02.05.2018 14:30

Как вы для начала сохраняете больше символов MaxInt (0x7FFFFFFF) в AnsiString? Вы должны были получить ошибки памяти от RTL задолго до того, как AnsiString достиг такого размера.

Remy Lebeau 02.05.2018 23:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
163
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как я вижу в Справка, оба параметра 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?

Alexandra Tupu 02.05.2018 14:20

Я не знаю этого фреймворка, но, как я вижу в справочнике, он должен быть похож на ExportFileName.Delete(1 << 31, ExportFileName.Length());.

NuPagadi 02.05.2018 14:30

Но длина возвращает int, 1 << 31 не шестнадцатеричный?

Alexandra Tupu 02.05.2018 14:44

@AlexandraTupu Нет. В C++ только литералы могут быть представлены в шестнадцатеричном формате.

NuPagadi 02.05.2018 14:46

строка такая же, не модифицируется

Alexandra Tupu 02.05.2018 14:57

@AlexandraTupu Вы уверены, что до проверки было больше 2 ^ 31? В противном случае его не следует изменять.

NuPagadi 02.05.2018 14:59

Прохладный! На stackoverflow.com мы голосуем за или принимаем ответы, если считаем, что они были полезны.

NuPagadi 02.05.2018 15:13
1 << 31 равен 0x80000000, что больше, чем MaxInt (0x7FFFFFFF). Delete() принимает int в качестве входных данных, значение 1 << 31 слишком велико для его обработки, и при передаче в качестве int значение будет отрицательным. 1 << 30 - это 0x40000000, что меньше MaxInt. Также обратите внимание, что 1-й параметр Delete() - это индекс, отсчитываемый от 1, а 2-й параметр - это количество удаляемых символов. При удалении символов в конце строки вы также можете использовать SetLength() вместо Delete().
Remy Lebeau 02.05.2018 21:34

Тип возврата AnsiString::Length - int, который имеет 32-разрядную подпись. Так что этот тест никогда не может быть успешным. Кроме того, функция SetLength принимает в качестве параметра int; передача ему 1ull << 31 вызывает поведение, определяемое реализацией (возможно, передача отрицательного значения)

M.M 03.05.2018 01:28

@ M.M Думаю, я заметил это в посте. Не могли бы вы прочитать это?

NuPagadi 03.05.2018 01:30

Я переместил предупреждение о целочисленном переполнении в начало сообщения и исправил параметры Delete и SetLength, чтобы никого не смущать.

NuPagadi 03.05.2018 12:01

Другие вопросы по теме