Delphi 2009 + Unicode + Char-size - PullRequest
       26

Delphi 2009 + Unicode + Char-size

6 голосов
/ 24 сентября 2008

Я только что получил Delphi 2009 и ранее читал некоторые статьи о модификациях, которые могут быть необходимы из-за перехода на строки Unicode. В основном упоминается, что sizeof (char) больше не гарантируется равным 1. Но почему это было бы интересно в отношении манипулирования строками?

Например, если я использую AnsiString: = 'Test' и делаю то же самое со строкой (которая теперь является юникодом), то я получаю Length () = 4, что правильно для обоих случаев. Не проверяя его, я уверен, что все другие функции манипуляции со строками ведут себя одинаково и решают внутренне, является ли аргумент строкой Юникода или чем-то еще.

Почему фактический размер символа будет интересен для меня, если я выполняю строковые манипуляции? (Конечно, если я использую строки в качестве строк, а не для хранения каких-либо других данных)

Спасибо за любую помощь! Хольгер

Ответы [ 7 ]

5 голосов
/ 24 сентября 2008

с Unicode SizeOf (SomeChar) <> длина (SomeChar) . По существу длина строки меньше суммы размера ее char s. Пока вы не предполагаете, SizeOf (Char) = 1 или SizeOf (SomeString [x]) = 1 (так как оба FALSE сейчас) или попробуйте поменять байт s на char s, тогда у вас не должно быть никаких проблем. В любом месте, где вы делаете что-то творческое, байт с Char с или String с, тогда вам нужно будет использовать AnsiString .

(SizeOf (SomeString) по-прежнему равен 4, независимо от длины, поскольку это по сути указатель с некоторой магией компилятора.)

4 голосов
/ 24 сентября 2008

Люди часто неявно преобразуют символы в байты в старом Delphi-коде, не задумываясь об этом. Например, при записи в поток. Когда вы записываете строку в поток, вы должны указать количество записываемых вами байтов, но вместо этого люди часто передают количество символов. См. этот пост от Криса Бенсена для другого примера.

Другой способ, которым люди часто делают это неявное преобразование, и более старый код - использование «строки» для хранения двоичных данных. В этом случае они действительно хотят байты, но тип данных ожидает символы. D2009 имеет лучший тип для этого .

1 голос
/ 24 сентября 2008

Я не пробовал Delphi 2009, но использую fpc, который также медленно переключается на Unicode. Я на 95% уверен, что все приведенное ниже относится и к Delphi 2009

В fpc (при поддержке юникода) так будет, чтобы функции типа length учитывали кодовую страницу. Таким образом, он вернет длину строки так, как ее увидит «человек». Если есть, например, два китайских символа, которые занимают два байта памяти в юникоде, length вернет 2, поскольку в строке два символа. Но строка займет 4 байта памяти. (+ память для подсчета ссылок и ведущего # 0, но это в стороне)

То, что вы больше не можете делать, это:

var p : pchar;
begin
  p := s[1];
  for i := 0 to length(string)-1 do
    begin
    write(p);
    inc(p);
    end;      
end;

Поскольку этот код - в примере с двумя китайскими символами - напишет неправильные два символа. А именно два байта, которые являются частью первого «реального» символа.

Вкратце: Length () больше не возвращает количество байтов, выделенных для строки, а количество символов. (До перехода на Unicode эти два значения были равны друг другу)

0 голосов
/ 28 июня 2015

Это может быть проблемой, если вы делаете вызовы API Windows. Или, если у вас есть устаревший код, который inc или dec из str [0] , чтобы изменить его длину.

0 голосов
/ 24 сентября 2008

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

0 голосов
/ 24 сентября 2008

(Конечно, если я использую строки в качестве строк, а не для хранения каких-либо других данных)

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

0 голосов
/ 24 сентября 2008

Фактический размер символа не должен иметь значения, если вы не выполняете манипуляции на уровне байтов.

...