String сколько байт
Перейти к содержимому

String сколько байт

  • автор:

Какой длины ваша строка?

Какой длины ваша текстовая строка? Вам понадобится ответ на этот вопрос, чтобы проверить допустимые ли данные ввел пользователь в поле данных ограниченной длины. Текстовое поле баз данных обычно ограничивают входные данные определенной длиной, так что вам надо сначала подтвердить длину текста, прежде чем отправить его. Какова бы ни была причина, нам всем иногда необходимо узнать длину текстового поля. Чтобы получить эту информацию, многие программисты используют метод length объекта String . И в большинстве случаев метод length обеспечивает правильный результат. Однако, это не единственный и не всегда верный способ узнать длину объекта String .

По крайней мере у вас есть три общих способа измерить длину текста, если вы используете платформу Java:

  1. количество знаков char в коде
  2. количество символов (characters) или кодовых единиц
  3. число байтов

Подсчет знаков char

В платформе Java используется Unicode Standard для определения символов. Unicode Standard определяет и фиксирует для каждого символа значение, состоящее из 16 битов, в пределе от U+0000 до U+FFFF. Префикс U+ означает допустимое значение в Юникоде как шестнадцатеричное число. В языке Java стандарт фиксированного размера символов удобно преобразуется в тип char . Таким образом значение char может быть представлено любым символом в 16-битном Юникоде.

Большинство программистов знакомы с методом length . Код, приведенный ниже, считает количество знаков char в примере строки. Обратите внимание, что пример объекта String содержит несколько простых символов и несколько символов, определенных в \u нотации языка Java. \u нотация определеяет шестнадцатеричное число и является аналогом нотации U+ , используемой Unicode Standard.

private String testString = «abcd\u5B66\uD800\uDF30» ;
int charCount = testString.length () ;
System.out.printf ( «char count: %d\n» , charCount ) ;

Метод length считает количество знаков char в объекте String . Вот что выведет этот код:

char count: 7

Подсчет символов

Когда Unicode версии 4.0 определяет важные новые символы выше U+FFFF, 16-битный тип char не может более представлять все символы. Начиная с Java 2 Platform, Standard Edition 5.0 (J2SE 5.0), платформа Java поддерживает новые символы Юникода — пары 16-битных знаков char , которые называются суррогатными парами ( surrogate pair ). Два знака char действуют как суррогатное представление символов Юникода в диапазоне от U+10000 до U+10FFFF. Символы в таком новом диапазоне называются дополнительные символы ( supplementary characters ).

Хотя единичный знак char все еще может представлять значение в Юникоде более U+FFFF, только суррогатная пара из двух char может представлять дополнительные символы. Главное или бóльшее значение в паре лежит в диапазоне от U+D800 до U+DBFF. Следующее или меньшее — от U+DC00 до U+DFFF. Unicode Standard выделил два этих диапазона, чтобы специально использовать в суррогатных парах. Стандарт также определяет алгоритм для преобразования между суррогатными парами и символами, значения которых лежат выше U+FFFF. Используя суррогатные пары, программисты могут представить любой символ в Unicode Standard. Такое специальное использование 16-битных знаков называется UTF-16 , и Java Platform пользуется UTF-16 для представления символов в Юникоде. Теперь тип char — это знак в коде UTF-16, необязательно целый символ Юникода (кодовая единица).

Метод length не может считать дополнительные символы, так как он считает только знаки char . К счастью в J2SE 5.0 API есть новый метод String : codePointCount(int beginIndex, int endIndex) . Этот метод показывает, сколько единиц Юникода (символов) между двумя индексами. Значения индексов ссылаются на код, обозначающий местоположение знака char . Значение выражения endIndex — beginIndex такое же как и значение, полученное с помощью метода length . Но это не всегда равно значению, возвращаемому методом codePointCount . Если ваш текст содержит суррогатные пары, вычисляемая длина сильно изменится. Суррогатная пара определяет код одного символа, который может состоять из одного или двух знаков char .

Чтобы узнать, сколько символов Юникода в строке, используйте метод codePointCount :

private String testString = «abcd\u5B66\uD800\uDF30» ;
int charCount = testString.length () ;
int characterCount = testString.codePointCount ( 0 , charCount ) ;
System.out.printf ( «character count: %d\n» , characterCount ) ;

Этот пример выведет следующее:

character count: 6

Переменная testString содержит два интересных символа: японский иероглиф, обозначающий «учение», и буква готского алфавита А ( GOTHIC LETTER AHSA ). Японский иероглиф в Юникоде имеет значение U+5B66 и такой же номер знака char в шестнадцатеричной системе \u5B66. Значение готской буквы — U+10330. В UTF-16 готская буква состоит из суррогатной пары \uD800\uDF30. Пара представляет один целый символ в Юникоде, таким образом число символов в строке равно 6, а не 7.

Подсчет байтов

Сколько байт в строке String ? Ответ зависит от использованной кодировки. Одной из наиболее распространенных причин спрашивать «сколько байт?» является желание убедится, что вы удовлетворили ограничением на длину строки в базе данных. Метод getBytes преобразует символы Юникода в байтовую кодировку (в кодировку, работающую не с символами, а байтами) и возвращает количество байт: byte[] . Одной из байтовых кодировок является UTF-8 . Это самая распространенная байтовая кодировка, потому что может точно представлять символы Юникода.

Далее представлен код, который преобразует текст в массив байтовых значений:

byte [] utf8 = null ;
int byteCount = 0 ;
try utf8 = str.getBytes ( «UTF-8» ) ;
byteCount = utf8.length;
> catch ( UnsupportedEncodingException ex ) ex.printStackTrace () ;
>
System.out.printf ( «UTF-8 Byte Count: %d\n» , byteCount ) ;

Наш набор символов определяет, сколько создано байтов. Кодировка UTF-8 преобразует один символ Юникода в один или несколько (до 4) 8-битовых единиц (байтов). Символы a , b , c и d требуют всего четыре байта. Японский иероглиф превращается в три байта. А готская буква занимает четыре байта. Вот каким будет результат:

UTF-8 Byte Count: 11

Рисунок 1. Строки имеют различную длину, зависящую от того, что вы считаете.

В заключение

Даже используя дополнительные символы, вы никогда не увидите разницу между возвращаемыми значениями метода length и метода codePointCount . Однако, когда вы используете символы выше U+FFFF, вам пригодится умение определять длину различными способами. Если вы будете посылать свои продукты в Японию или Китай, то наверняка попадете в ситуацию, когда методы length и codePointCount вернут различные значения. Базы данных и некоторые форматы публикаций поощряют использование в качестве кодировки UTF-8. Но даже в этом случае измерение длины текста может дать различные результаты. В зависимости от того, как вы будете использовать длину, у вас есть различные способы ее измерить.

Дополнительная информация

Используйте эти ресурсы, чтобы найти информацию по теме данного технического совета:

  • Сайт Unicode Standard
  • JSR 204: Поддержка дополнительных символов в Юникоде
  • Документация по классу символов (Character)
  • Статья: Дополнительные символы в платформе Java
  • Поддержка кодировок

String

Строки произвольной длины. Длина не ограничена. Значение может содержать произвольный набор байт, включая нулевые байты. Таким образом, тип String заменяет типы VARCHAR, BLOB, CLOB и т. п. из других СУБД.

При создании таблиц для строк можно указывать числовые параметры (например VARCHAR(255) ), но СlickHouse их проигнорирует.

Кодировки​

В ClickHouse нет понятия кодировок. Строки могут содержать произвольный набор байт, который хранится и выводится, как есть. Если вам нужно хранить тексты, рекомендуется использовать кодировку UTF-8. По крайней мере, если у вас терминал работает в кодировке UTF-8 (это рекомендуется), вы сможете читать и писать свои значения без каких-либо преобразований. Также, некоторые функции по работе со строками, имеют отдельные варианты, которые работают при допущении, что строка содержит набор байт, представляющий текст в кодировке UTF-8. Например, функция length вычисляет длину строки в байтах, а функция lengthUTF8 — длину строки в кодовых точках Unicode, при допущении, что значение в кодировке UTF-8.

Типы данных

Строка. Тип данных string. Строковые переменные, их описание. Длина строки. Операции над строками

Строка (string) — это последовательность литер. Литерные строки уже использовались нами в качестве аргументов операторa write при изучении темы «Ввод-вывод». Теперь познакомимся с ними подробнее.

Тип данных (string) определяет строки с максимальной длиной 255 символов. Переменная этого типа может принимать значения переменной длины.

MaxLine : string;
City : string[30]

Строковая переменная может иметь атрибут длины, определяющий ее максимальную длину.

Текущая длина строковой переменной может быть определена с помощью встроенной функции Length. Для заданного значения типа string эта функция возвращает целое значение, показывающее количество литер в строке.

Выражения, в которых операндами служат строки, называются строковыми выражениями.

Над строками определены следующие операции:

1. Операция конкатенации (+) применяется для сцепления нескольких строк в одну.

Например,
SumStr := ‘Турбо ‘+’Паскаль ‘+’7.0’

Если строки имеют различную длину, но в их общей части символы совпадают, считается, что более короткая строка меньше, чем более длинная.

Строки считаются равными, если они совпадают по длине и содержат одни и те же символы на соответствующих местах в строке.

Для присваивания строковой переменной результата строкового выражения используется оператор присваивания. Если значение переменной после выполнения оператора присваивания превышает по длине максимально допустимую при описании величину, то все лишние символы справа отбрасываются.

Допускается смешение в одном выражении операндов строкового и символьного типа.

К отдельным символам строки можно обратиться по номеру (индексу) данного символа в строке.

Например, чтобы обратиться к третьему символу строки SumStr надо записать SumStr[3]. Запись SumStr[0] дает значение текущей длины строки.

Для эффективного программирования алгоритмов обработки текстов необходимо хорошо понимать внутреннюю структуру представления строк в памяти. Строки реализованы достаточно просто. Для хранения строковых переменных выделяется количество байтов памяти, на единицу большее максимальной длины строки. Начальный байт этой памяти отводится для хранения текущей длины строки, следующие байты — для символов самой строки. Так как элементы строк стандартно нумеруются целыми числами, начиная с единицы, байт с длиной строки можно считать нулевым ее элементом. Такая структура памяти допускает прямой доступ к ее элементам.

Важно отметить, что имеется возможность динамически управлять текущей длиной строки. Следующая программа показывает автоматическое изменение длины строки после тех или иных операций с нею. Обратите внимание, что общий (определяемый с помощью стандартной функции SizeOf) размер памяти, отведенной для хранения строки все время остается неизменным.

Program StringLength;
Var
S : string;
Begin
S:=»;
writeln (S,’ ‘,SizeOf(S),’ ‘,Length(S));
S:=’Пример длинной строки’;
writeln (S,’ ‘,SizeOf(S),’ ‘,Length(S));
Delete(S,7,8);
writeln (S,’ ‘,SizeOf(S),’ ‘,Length(S));
S:=S+’ символов’;
writeln (S,’ ‘,SizeOf(S),’ ‘,Length(S));
End.

Внимание! При решении задач со строковыми переменными Вы можете столкнуться с распространенной трудно обнаруживаемой ошибкой, когда после присваивания некоторым элементам строки символов ни содержимое, ни длина строки не изменяются. Разберемся, с чем это связано.

Очень важно понимать, что при доступе к некоторому элементу строки значение ее текущей длины не проверяется. Это иллюстрирует следующая программа:

Program StringElements;
Var
S : string;
Begin
S:=’ABCD’;
writeln (S,’ ‘,Length(S));
S[5] := ‘E’;
writeln (S,’ ‘,Length(S));
End.

Присваивание пятому элементу строки некоторого значения не изменяет длину строки, что подтверждает вывод на экран ее содержимого и длины (конечно само присваивание реально произошло, но на значение текущей длины строки в нулевом байте это никакого влияния не оказало). Работа с элементами строки без учета ее текущей длины и является ошибкой программиста. Посмотрите следующую программу:

Program StringElements2;
Var
Str : string[26];
i : integer;
Begin
Str:=’A’;
for i := 1 to 26 do
Str[i] := Chr (Ord(‘A’)+i-1);
writeln(Str);
End.

Предполагается, что данная программа должна сформировать строку из 26 символов, содержимым которой является последовательность заглавных букв латинского алфавита. Однако вызов процедуры writeln показывает, что содержимым переменной Str будет строка из одного символа ‘А’. Природа совершенной ошибки заключается в том, что присваивание значений элементам строки не влияет на текущую длину, которая была установлена равной 1 при первом присваивании. Поэтому правильной будет следующая программа:

Program stringElements3;
Var
Str : string[26];
i : char;
Begin
Str:=»;
for i := ‘A’ to ‘Z’ do
Str := Str + i;
writeln(Str);
End.

Операция конкатенации, как и все стандартные операции, работающие со строками, в отличие от поэлементного присваивания, изменяет длину строки, что дает корректный результат. Кроме того, вторая программа работает непосредственно с символами букв. Наконец, не следует забывать инициализировать строку перед ее заполнением (первый оператор программы). В противном случае, так как начальная длина строки является неопределенной, можно получить произвольный результат; не стоит рассчитывать на то, что в нулевом байте стоит ноль.

Для обработки строковых данных можно использовать встроенные процедуры и функции:

    Delete (Str, Poz, N) — удаление N символов строки Str, начиная с позиции Poz.

Как узнать длину строки в байтах?

Как узнать длину строки? И всегда ли она будет по байтам одинаково занимать?

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

Ответы с готовыми решениями:

Как узнать длину строки?
Как узнать длинну строки string xc = "asdfghjk"; byte l = xc.length(); выше код дает.

Как узнать длину строки
Казалось бы, вопрос глупый. Берём что-то наподобие string s = "Veterinar"; int len = s.Length; В.

Как узнать длину указателя (в байтах)?
как узнать длину указателя(в байтах) sizeof(указатель)почему то не работает?

Как определить длину строки в байтах
как быть, если строка юникодная? Нужно контролировать именно размер занимаемый в памяти, на не.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *