2012-01-16 4 views
5

Я получил источник старого проекта и должен изменить мелочи, но у меня возникли большие проблемы из-за того, что для этого было только delphi 2010.проблемы с строкой, переносящие Delphi 3 в 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». Это приложение читает файл, но с неправильным контентом.

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

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

+0

Использование AnsiString в записывать результаты определения также в компиляторе: «финализация bbil нужна». Таким образом, замыкание этих AnsiString "pfad: AnsiString [255];" также не работает: ", ожидаемый, но [найденный". Что мне, вероятно, нужно isa ShortAnsiString? – rseffner

+2

IMO ваш код не должен компилироваться в Delphi 3; try 'path: array [0..N] of AnsiChar;', где N - некоторая константа, может быть 255. – kludg

+2

Сделайте, как говорит Дэвид, объявите строку как «ShortString». Для выравнивания записи попробуйте директиву упакованной записи, если это поможет. Для того, чтобы этот код работал в D3, должна была использоваться директива {$ H-}. –

ответ

5

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

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

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

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

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

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

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

+0

Дэвид, я думаю, что совет 'ShortString' правильный, только размер записи должен совпадать. Директива выравнивания может разрешить эту или, возможно, декларацию упакованной записи. –

+0

Использование ShortString в качестве замены «String» в наборе записей было одной из первых вещей, которые я сделал. Но это работает не так, как ожидалось, все прочитанные datarecords были хламом ;-(Теперь я должен прочитать о «директиве упакованных записей», потому что я этого не знаю. – rseffner

+1

Просто объявляйте тип как 'упакованная запись' вместо' record'. удалит выравнивания, сделанные компилятором. Чтобы увидеть размер записи, попробуйте использовать 'SizeOf (bbil)'. –

2

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

"строка" <> "строка [255]" <> "ShortString" <> AnsiString

Назад в старые времена DOS/Turbo Pascal, "струны" действительно были ограничены 255 символов. Во многом потому, что первый байт содержал длину строки, а байт может иметь только значение от 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" для двоичных записей.

+1

В терминологии Delphi длинные строки относятся как к AnsiString, так и к UnicodeString, последний из которых представляет собой новый тип строки, введенный на D2009. И WideString отличается снова, это оболочка вокруг COM BSTR. –

+2

@ rseffner - Терминология может ввести в заблуждение. В основном ошибка Microsoft. Пожалуйста, просмотрите ссылки, которые я привел (в частности, статью about.com), чтобы понять строки. И, пожалуйста, экспериментируйте с «sizeof()», чтобы устранить проблемы с упаковкой и выравниванием с вашими двоичными записями. – paulsm4

+1

Терминология совершенно ясна и не имеет отношения к MS. Этот язык подготовлен Embarcadero. Мой предыдущий комментарий пытался помочь вам в устранении различных ошибок в вашем ответе. Как бы то ни было, это довольно неточно. –

0

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

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

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

path : ShortString[255]; 

Тогда вы могли бы читать и писать хорошо в обоих Дельфы 3 и 2010

+0

С другой стороны, у delphi 3 не был тип shortstring, вы должны определить его как строку в delphi 3. –