Есть ли способ узнать, использует ли персонаж 1 или 2 байта в Delphi 2009? - PullRequest
4 голосов
/ 10 октября 2008

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

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

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

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

Ответы [ 7 ]

5 голосов
/ 10 октября 2008

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

if ord(c) < 128 then
    // is an ascii character
4 голосов
/ 10 октября 2008

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

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

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

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

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

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

2 голосов
/ 24 декабря 2008

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

2 голосов
/ 10 октября 2008

Если вы не хотите использовать 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;
1 голос
/ 07 ноября 2008

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

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

0 голосов
/ 21 октября 2008

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

0 голосов
/ 10 октября 2008

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

...