Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Нетипизированные указатели [D7]


Страницы:   1 2

Vitaliy____ ©   (2008-07-31 05:51:00) 

Доброе время суток!
Есть такая задача: организовать чтение/запись из файла в формате
параметр=значение.
Программа должна читать те параметры, что ей "известны" по имени.
Положим, они будут 3-х типов: целое, вещественное, строка.
Помогите с синтаксисом структуры, в которой можно бы было хранить указатель на один из этих 3-х типов данных и пример работы  (запись значения по этому указателю).
Конечно можно сделать 3 указателя в каждой записи, но 1) могут добавится другие типы данных 2) Наверняка можно без извращений и потерь памяти - просто я не знаю как это в делфи.


Ega23   (2008-08-05 10:05:00) [1]


> Категорически не согласен.


Рекомендую заглянуть в CPU.


Vitaliy____   (2008-08-05 09:00:00) [2]


> Так ты что же, всю эту шнягу затеял искл-но ради отладки
> ?!

Совсем не понял к чему это...
Зачем это все затеяно написано в [12] (там жирненьким даже выделено...).
По-моему все превращается в оффтоп...


Сергей М.   (2008-08-05 08:23:00) [3]


> Vitaliy____   (05.08.08 07:37) [20]


Так ты что же, всю эту шнягу затеял искл-но ради отладки ?!

Мда)..

А когда ты собираешься забить гвоздь, ты случаем не вызываешь перед этим бригаду скорой помощи, типо, ежели что, сразу диагноз поставить или  в морг отвезти ?)


Vitaliy____   (2008-08-05 07:37:00) [4]

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

> А её не надо "освобождать".

Категорически не согласен. Сколько пишу - всегда пригождалось: даже если класс существует до конца работы программы и память будет освобождена средой, очень полезно с самого начала сделать конструктор/деструктор и таким образом ловить ошибки типа выхода за границы массива и т.д. - если мы запортили память - удаление обычно не проходит и мы сразу знаем у какой структуры проблемы.


Ega23   (2008-08-04 12:21:00) [5]


> По крайней мере у меня проблем не было (обычно ошибки памяти
> вылазят на деструкторе класса, когда мы пытаемся освободить
> эту самую память).


А её не надо "освобождать".

Так тебе это дело в процессе работы программы надо хранить? И не сохранять_читать в файл (из файла)?


Vitaliy____   (2008-08-04 12:13:00) [6]

По-моему, тут мы куда-то не туда лезем....
Есть строка/целое/вещественное, которое надо запомнить на случай если параметр не прочитан. Как верно заметили в [5], чтение справки часто избавляет от многих хлопот. Variant подходит именно для хранения этих типов данных. Как я понимаю, пример из справки

var
 V1, V2, V3, V4, V5: Variant;
 I: Integer;
 D: Double;
 S: string;
begin
 V1 := 1; { integer value }
 V2 := 1234.5678; { real value }
 V3 := 'Hello world!'; { string value }
 V4 := '1000'; { string value }
 V5 := V1 + V2 + V4; { real value 2235.5678}
 I := V1; { I = 1 (integer value) }
 D := V2; { D = 1234.5678 (real value) }
 S := V3; { S = 'Hello world!' (string value) }
 I := V4; { I = 1000 (integer value) }
 S := V5; { S = '2235.5678' (string value) }

end;

Позволяет быть уверенным, что строки в Variant хранятся нормально. По крайней мере у меня проблем не было (обычно ошибки памяти вылазят на деструкторе класса, когда мы пытаемся освободить эту самую память).
Так что думаю все корректно.


Ega23   (2008-08-01 14:57:00) [7]


> Не понял, он что сам не разберется? В справке просто присваивают
> строку и она где-то хранится, видимо они нормально работу
> со строками реализовали. В ансистринг же мы не задумываемся.
> ..


Я тебя не понимаю.
Опиши ещё раз: что у тебя есть и что ты хочешь получить на выходе.


Vitaliy____   (2008-08-01 13:49:00) [8]

Не понял, он что сам не разберется? В справке просто присваивают строку и она где-то хранится, видимо они нормально работу со строками реализовали. В ансистринг же мы не задумываемся...


Ega23   (2008-08-01 13:43:00) [9]

Дык в том, что где тогда твой вариант будет храниться? Размер варианта - 16 байт. Ну будет там где-то адрес твоей строки. А сами данные?


Vitaliy____   (2008-08-01 13:14:00) [10]

Нет, здоровых там не предполагается. В основном - целые и вещественные параметры. А если строка, то не больше 100 символов.
Кстати, а в чем узкое место? Разве в Variant не так как в AnsiString? Здоровый - ну и пусть себе хранится раз надо... Если есть какие-то мысли, поясни в чем узкость места...


Ega23   (2008-08-01 12:59:00) [11]

Узкое место - DefaultValue. Представь, что это какой-то здоровый стринг.


Vitaliy____   (2008-08-01 12:38:00) [12]

Связь простая. Может я "быстро" писал первый пост и не совсем понятно что хотел ;)

Все сводится к такой структурке:


type ParamLinkElem=record
name:string;             // Имя параметра
type_v:integer;         // Тип данных параметра
Initialise:boolean;      // Прочитан ли параметр из файла
link:Pointer;             // Ссылка на переменную, где хранится параметр
DefaultValue:variant; // Значение по умолчанию для данного параметра
end;


Имеется массив элементов типа ParamLinkElem. В конструкторе класса, занимающегося вводом/выводом прописываются значения этой "связующей" структуры (параметры читаются для других классов, поэтому нужна была нетипизированная ссылка) .
Когда мы читаем из файла параметры, мы находим по имени что это за параметр, получаем его тип и куда надо записать.
Если не все параметры были прочитаны (флаг Initialise при чтении не выставлен), то по адресу link записывается DefaultValue (вот тут потребовался тип variant - так как нужно хранить разные типы данных)

Вот теперь, когда это все работает - можно критиковать :)
Закономерен вопрос " для чего все это нужно". Ситуация такая: для данной формы часто приходится менять сохраняемые параметры (какие-то становятся ненужными или появляются новые). Так вот, прога должна "безболезненно" воспринимать изменение "версии" файла сохранения. Если у нас в нем что-то лишнее - оно будет проигнорировано, так как параметра с таким именем в массиве не найдется; Если мы чего-то не прочтем - будет подставлено значение по умолчанию.


Плохиш   (2008-07-31 17:53:00) [13]


> в файле целые должны быть строкой а не бинарно


> variant и pointer достаточно было

Казалось бы, какая связь...


Vitaliy____   (2008-07-31 14:13:00) [14]

К сожалению, не пойдет - в файле целые должны быть строкой а не бинарно.
Уже сделано - variant и pointer достаточно было. Тему закрыть можно.


Ega23   (2008-07-31 12:03:00) [15]


procedure StreamReadString(Stream : TStream; var Value : string;
   const Size : Integer);
begin
 SetLength(Value, Size);
 Stream.ReadBuffer(PChar(Value)^, Size);
end;

//*****************************************************************************

procedure StreamWriteString(Stream : TStream; const Value : string;
   const TagID : Cardinal);
var
 BlockSize : Cardinal;
begin
 BlockSize := Length(Value);
 Stream.WriteBuffer(TagID, 4);
 Stream.WriteBuffer(BlockSize, 4);
 Stream.WriteBuffer(PChar(Value)^, BlockSize);
end;

//*****************************************************************************

procedure StreamReadDateTime(Stream : TStream; var Value : TDateTime);
begin
 Stream.ReadBuffer(Value, SizeOf(TDateTime));
end;

//*****************************************************************************

procedure StreamWriteDateTime(Stream : TStream; const Value : TDateTime;
   const TagID : Cardinal);
var
 BlockSize : Cardinal;
begin
 BlockSize := SizeOf(TDateTime);
 Stream.WriteBuffer(TagID, 4);
 Stream.WriteBuffer(BlockSize, 4);
 Stream.WriteBuffer(Value, BlockSize);
end;

//*****************************************************************************

procedure StreamReadGUID(Stream : TStream; var Value : TGUID);
begin
 Stream.ReadBuffer(Value, SizeOf(TGUID));
end;

//*****************************************************************************

procedure StreamWriteGUID(Stream : TStream; const Value : TGUID;
   const TagID : Cardinal);
var
 BlockSize : Cardinal;
begin
 BlockSize := SizeOf(TGUID);
 Stream.WriteBuffer(TagId, 4);
 Stream.WriteBuffer(BlockSize, 4);
 Stream.WriteBuffer(Value, BlockSize);
end;

//*****************************************************************************

procedure StreamReadBoolean(Stream : TStream; var Value : Boolean);
begin
 Stream.ReadBuffer(Value, SizeOf(Boolean));
end;

//*****************************************************************************

procedure StreamWriteBoolean(Stream : TStream; const Value : Boolean;
   const TagID : Cardinal);
var
 BlockSize : Cardinal;
begin
 BlockSize := SizeOf(Boolean);
 Stream.WriteBuffer(TagID, 4);
 Stream.WriteBuffer(BlockSize, 4);
 Stream.WriteBuffer(Value, BlockSize);
end;

//*****************************************************************************

procedure StreamReadInteger(Stream : TStream; var Value : Integer);
begin
 Stream.ReadBuffer(Value, SizeOf(Integer));
end;

//*****************************************************************************

procedure StreamWriteInteger(Stream : TStream; const Value : Integer;
   const TagID : Cardinal);
var
 BlockSize : Cardinal;
begin
 BlockSize := SizeOf(Integer);
 Stream.WriteBuffer(TagID, 4);
 Stream.WriteBuffer(BlockSize, 4);
 Stream.WriteBuffer(Value, BlockSize);
end;

//*****************************************************************************


Сергей М.   (2008-07-31 11:45:00) [16]


> Вот как, за меня уже все сделали


И даже кучу примеров предоставили по использованию этого самого за тебя сделанного.


oldman   (2008-07-31 09:27:00) [17]


> Программа должна читать те параметры, что ей "известны"
> по имени.


Ini файлы отменили?


Vitaliy____   (2008-07-31 09:01:00) [18]

Вот как, за меня уже все сделали... Замечательно. А я-то думал. Чтож, это очень даже здорово...


Leonid Troyanovsky   (2008-07-31 08:10:00) [19]


> Vitaliy____   (31.07.08 05:51)  

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

RTFM: variant type.

--
Regards, LVT.


Vitaliy____   (2008-07-31 07:07:00) [20]

Вроде понятно. Отладка покажет. Спасибо ;)
Будем поглядеть...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо