Есть ли способ узнать, использует ли символ 1 или 2 байта в Delphi 2009?


Delphi 2009 изменил свой тип строки, чтобы использовать 2 байта для представления символа,что позволяет поддерживать наборы символов unicode. Теперь, когда вы получаете один sizeof(строка) вы получаете length(строка) * оператор sizeof(тип char) . Sizeof (char) в настоящее время составляет 2.

Меня интересует, знает ли кто-нибудь способ, с помощью которого на основе символов можно узнать, поместится ли он в один байт, например, узнать, является ли символ ascii или Unicode.

Что меня в первую очередь интересует зная, до того, как моя строка отправится в базу данных (oracle, Documentum), сколько байт строка будет использовать.

Мы должны быть в состоянии применять ограничения перед рукой и в идеале (поскольку у нас есть большая установленная база) без необходимости изменять базу данных. Если строковое поле допускает 12 байт, в delphi 2009 строка длиной 7 всегда будет отображаться как использующая 14 байт, хотя после того, как она попадет в БД, она будет использовать только 7, Если ascii или 14, Если двойной байт, или где-то между ними, если смесь.

7 4

7 ответов:

Вы можете проверить значение символа:

if ord(c) < 128 then
    // is an ascii character

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

Количество байтов, которые будет использовать ваша строка, полностью зависит от кодировки символов, с которой она будет храниться. Если это UTF-16, тип строки по умолчанию в Delphi, то он всегда будет составлять 2 байта на символ, исключая суррогаты.

Наиболее вероятный кодировка, предполагающая, что база данных использует кодировку Unicode, однако, является UTF-8. Это кодировка переменной длины: символы могут требовать от 1 до 4 байт, в зависимости от символа. Вы можете увидеть диаграмму в Википедии, как отображаются диапазоны.

Однако, если вы вообще не меняете схему базы данных, это должно означать одно из трех:

  1. в настоящее время вы храните все в двоичном виде, а не текстовым способом (обычно не очень хорошо выбор)
  2. база данных уже хранит Юникод и подсчитанные символы, а не байты (в противном случае, у вас была бы проблема сейчас, тем более в случае акцентированных букв)
  3. база данных хранится в однобайтовой кодовой странице, такой как Windows-1252, что предотвращает хранение данных в Юникоде вообще (что делает его не проблемой, потому что символы будут храниться так же, как и раньше, хотя вы не можете использовать Юникод)

Я не знаком с Oracle, но если вы посмотрите на MSSQL, они есть два разных типа данных: varchar и nvarchar. Varchar считается в байтах, а nvarchar - в символах, поэтому он подходит для Unicode. MySQL, с другой стороны, имеет только varchar, и он всегда считается в символах (начиная с 4.1). Поэтому вы должны проверить документацию Oracle и схему базы данных, чтобы получить решающий ответ на вопрос, Является ли это проблемой вообще.

Если вы не хотите использовать Unicode в Delphi 2009, Вы можете использовать тип AnsiString. Но зачем тебе это делать?

Громоздким, но допустимым тестом может быть:

function IsAnsi(const AString: string): Boolean;
var
  tempansi : AnsiString;
  temp : string;
begin
  tempansi := AnsiString(AString);
  temp := tempansi;
  Result := temp = AString;
end;

Вы можете использовать функцию StringElementSize, чтобы узнать, является ли строка Unicode или ANSI. Чтобы проверить, является ли символ ANSI, используйте TCharacter.IsAnsi Функция класса в Символе.блок па.

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

Как насчет преобразования в UTF8String? Символы Ansi будут занимать 1 байт. Имейте в виду, что в UTF-8 символы Юникода могут занимать более 2 байт.

Поскольку с AnsiString 1 char = 1 байт и с Unicode String 1 char = 2 байта, простой тест для выполнения IsAnsiString:= sizeof (aString)=length (aString);

Символ ASCII всегда помещается в один байт. Вы не можете сказать то же самое для символа unicode, так как это зависит от того, как он кодируется. Вы не можете видеть из одного байта, является ли он символом ASCII или unicode, или если это вообще символ. Так в чем же заключается Ваш вопрос? И зачем тебе это знать? Я думаю, что вы неправильно поняли unicode или я неправильно понял ваш вопрос.