проблемы со строкой при переносе Delphi 3 в Delphi 2010 - PullRequest
5 голосов
/ 16 января 2012

У меня есть источник более старого проекта, и мне нужно что-то менять, но у меня большие проблемы из-за того, что для этого нужен только Delphi 2010.

Определена запись:

bbil = record
  path : string;
  pos: byte;
  nr: Word;
end;

позже это определение используется для чтения из файла:

b_bil: file of bbil;
pbbil: ^bbil;
l_bil : tlist;

while not(eof(b_bil)) do
  begin
    new(pbbil);
    read(b_bil, pbbil^);
    l_bil.add(pbbil);
  end

Основная проблема заключается в том, что компилятор не принимает тип "строка" в записи, потому что он хочет "финализацию". Поэтому я попытался изменить «string» на «string [255]» или «shortstring». При этом приложение читает файл, но с неверным содержимым.

Мой вопрос заключается в том, как преобразовать старый тип «string», с помощью которого файлы были записаны, в «новые» типы в Delphi 2010.

Я уже много пробовал, например. "{$ H-}". Добавление в запись только одного символа больше показывает, что файл правильный, потому что файл читается почти корректно, но усечено на один символ больше на каждый набор данных - длина lengthbyte + 255 символов кажется правильной для определения, но короткая строка не совпадает.

Ответы [ 3 ]

5 голосов
/ 16 января 2012

Ик!Похоже, ваш код либо предшествует датам, либо не использует длинные строки.Если вы хотите получить то же поведение, что и в вашем старом Delphi, тогда вам нужно заменить string на ShortString.

Я вижу, что вы уже пробовали это, и сообщаю, что это не удалось.Это действительно единственное объяснение, которое имеет какой-то смысл для меня, потому что все другие типы строк по сути являются указателями, и поэтому единственный способ, которым read мог бы когда-либо работать, - это ShortString.Миграция, которую вы пытаетесь выполнить, огромна, и вы, вероятно, столкнулись с огромным количеством проблем.

@ LU RD отмечает, что расположение записей в разных версиях Delphi может отличаться, поскольку вы не используете * 1009.* массив.Вы можете исследовать макет записи, используя две имеющиеся у вас версии Delphi.Вам нужно договориться о том, чтобы размер записей совпадал между версиями и чтобы смещения полей также совпадали.

На основе приведенных ниже комментариев добавление байта заполнения между pos и nr решит ваши проблемы.

bbil = record
  path : string;
  pos: byte;
  _pad: byte;
  nr: Word;
end;

Вы также можете добиться того же эффекта, установив параметр компилятора $ALIGN на {$ALIGN ON}, что, как я думаю, будет происходить с вещами.

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

2 голосов
/ 16 января 2012

Только запомните:

"string" <> "string [255]" <> "shortstring" <> AnsiString

В старые времена DOS / Turbo Pascal "строки" былидействительно ограничено 255 символами.Во многом потому, что 1-й байт содержал длину строки, а байт может иметь значение только от 0 до 255.

Это больше не проблема в современных версиях Delphi.

" ShortString"- это тип для старого типа строки DOS / Pascal.

" LongString "был типом строки по умолчанию в течение длительного времени (включая Borland Delphi 2006, который я в настоящее время использую для большинствапроизводственная работа).Начиная с Delphi 3. Delphi 2009, LongStrings содержал 8-битные символы и был ограничен только доступной памятью.Начиная с Delphi 3. Delphi 2009, «LongStrings» были синонимичны с «AnsiStrings».

В последних версиях Delphi (Delphi 2009 и более поздних, включая новый Delphi XE2) все теперь по умолчанию используют многобайтовый Unicode «WideString».Струны. WideStrings , как и AnsiStrings, также эффективно "неограниченны" по максимальной длине.

Эта статья объясняет более подробно:

http://delphi.about.com/od/beginners/l/aa071800a.htm

PS: Попробуйте использовать "sizeof (bbil)" и " Packed " для двоичных записей.

0 голосов
/ 05 июня 2012

Может быть, я что-то упускаю, но, как я вижу, твой код delphi 3 тоже не работает. Попробуйте определить размер вашей записи:

bbil = record
  path : string;
  pos: byte;
  nr: Word;
end;

путь (все от 1 до 256 - один байт для длины, остаток для данных), pos (1 байт), nr (2 байта), благодаря чему размер данных вашей записи может варьироваться от 1 + 1 + 2 = 4 байта до 256 + 1 + 2 = 259 байт. В этом случае вы получите мусор из файла в любом случае, так как ваша программа не может определить, сколько байтов нужно прочитать, прежде чем читать данные. Я предлагаю вам исправить вашу запись так, чтобы строка имела фиксированный размер, например:

path : ShortString[255];

Тогда вы сможете писать и читать хорошо как в Delphi 3, так и в 2010 году.

...