Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.01.27;
Скачать: CL | DM;

Вниз

В цикле последовательно обратиться к полям записи.   Найти похожие ветки 

 
AlexanderMS ©   (2007-12-26 16:03) [0]

Скажите, пожалуйста, как в цикле последовательно обратиться к полям записи, зная их размер?
Есть переменная типа record. Необходимо в цикле последовательно прочитать из текстового файла значения полей (каждой поле - 1 байт). То есть не так (var F: TextFile):

Readln(F, S);
MyRec.Field1 := strtoint(S);
Readln(F, S);
MyRec.Field2 := strtoint(S);
Readln(F, S);
MyRec.Field3 := strtoint(S);
...


А вот так:


for Line := 0 to RecCount - 1 do
begin
 Readln(F, S);
//  MyRec.Fields[Line] := strtoint(S); тут нужен трюк
end;


Как можно осуществить сабж?


 
Anatoly Podgoretsky ©   (2007-12-26 16:08) [1]

Это вообще абсурд, цикл по записям, а обращение к массиву полей.
И у записей нет никакого массива! У него есть только имена.


 
Palladin ©   (2007-12-26 16:11) [2]

хочешь в цикле, сделай внутри записи массив, только нафик тогда нужна запись?


 
Anatoly Podgoretsky ©   (2007-12-26 16:15) [3]

Ты читать умеешь?

> И у записей нет никакого массива! У него есть только имена.


 
AlexanderMS ©   (2007-12-26 16:19) [4]

Я имел ввиду обратиться к полям записи, используя, если возможно, обращение к памяти: начальный адрес записи и смещение по одному байту. Это можно сделать? Если можно, то как?

> Это вообще абсурд, цикл по записям, а обращение к массиву
> полей.
> И у записей нет никакого массива! У него есть только имена.

//  MyRec.Fields[Line] := strtoint(S); тут нужен трюк
Здесь комментарий стоит, и никакого массива не планируется: я думал, так легче понять. Оказалось, наоборот.


 
Сергей М. ©   (2007-12-26 16:21) [5]

т.е. объявление записи у тебя выглядит так:

TMyRec = packed record
 Field1: Byte;
 Field2: Byte;
..
 FieldN: Byte;
end;

??


 
AlexanderMS ©   (2007-12-26 16:22) [6]


> Сергей М. ©   (26.12.07 16:21) [5]
> т.е. объявление записи у тебя выглядит так:


Да, только без packed. :) Но можно приписать.


 
Palladin ©   (2007-12-26 16:23) [7]


> [3] Anatoly Podgoretsky ©   (26.12.07 16:15)

умею, если трудности с восприятием информации, то я предлагал следующее

TMyRecord=Record
Fields:Array of String;
End;


 
Сергей М. ©   (2007-12-26 16:26) [8]


> можно приписать


Да не не можно, а нужно !

Но тогда объясни, зачем тебе цикл ?
И какое отношение декларатор TextFile имеет к TMyRec = packed record ?


 
Palladin ©   (2007-12-26 16:33) [9]


> [8] Сергей М. ©   (26.12.07 16:26)

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


 
Anatoly Podgoretsky ©   (2007-12-26 16:33) [10]

> Palladin  (26.12.2007 16:23:07)  [7]

Вообще то у него байты, но это несущественно


 
Palladin ©   (2007-12-26 16:33) [11]

вот я и говорю нафик запись то нужна... массив чем не устраивает?


 
Sapersky   (2007-12-26 16:34) [12]

AlexanderMS ©   (26.12.07 16:03)

Можно использовать вариантные поля в записях (см. хелп, Variant parts in records).
 TRecord = record
   Case integer of
     0 : (Field1, Field2, Field3 : Byte);
     1 : (Fields : array [0..2] of Byte);
   end;
Само собой, правильно оно будет работать только в том случае, если поля Field1 - Field3 имеют одинаковый размер.


 
Сергей М. ©   (2007-12-26 16:36) [13]


> Palladin ©   (26.12.07 16:33) [9]
>
>


> Судя по первому посту, у него текстовый файл


Вот и непонятно, каким образом он желает сопоставить записи переменной длины в текстовом файле с записью фиксированного размера в памяти приложения..


 
AlexanderMS ©   (2007-12-26 16:39) [14]


> Но тогда объясни, зачем тебе цикл ?

Чтобы не писать:
Readln(F, S);
MyRec.FieldX := strtoint(S);

много раз...
А запись нужна для удобства обращения.


> И какое отношение декларатор TextFile имеет к TMyRec = packed
> record ?

Никакого, просто для примера.


 
AlexanderMS ©   (2007-12-26 16:40) [15]


> Sapersky   (26.12.07 16:34) [12]

Спасибо, вроде неплохой вариант.


 
Palladin ©   (2007-12-26 16:41) [16]


> [13] Сергей М. ©   (26.12.07 16:36)

да почему перменной длинны, судя, опять же по первому посту, у него там циферки :) на одну строчку - одна циферка


 
AlexanderMS ©   (2007-12-26 16:42) [17]


> Спасибо, вроде неплохой вариант.

То есть спасибо большое, то что надо!


 
Anatoly Podgoretsky ©   (2007-12-26 16:42) [18]

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


 
Сергей М. ©   (2007-12-26 16:43) [19]


> Palladin ©   (26.12.07 16:41) [16]



> на одну строчку - одна циферка
>


Вовсе не очевидно.


 
Palladin ©   (2007-12-26 16:44) [20]

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

Type
TMyRec=Packed Record
 f1,f2,f3,f4,f5,f6:Byte;
End;

Var
r:TMyRec;
a:Array [1..6] of Byte absolute r;
s:String;
function readlnn:byte;
Begin
Readln(f,s);
Result:=StrToInt(s);
End;

for i:=1 to 6 do a[i]:=readlnn;


 
Palladin ©   (2007-12-26 16:47) [21]


> [19] Сергей М. ©   (26.12.07 16:43)

ну как не очевидно, а:

Readln(F, S);
MyRec.Field1 := strtoint(S);
Readln(F, S);
MyRec.Field2 := strtoint(S);
Readln(F, S);
MyRec.Field3 := strtoint(S);

разве не говорит об ожидаемом четком формате файла?


 
Сергей М. ©   (2007-12-26 16:51) [22]


> Palladin ©   (26.12.07 16:47) [21]


Не-а.
Известно только, что файл текстовый.

Т.е. вида

154
1
0
66
255
33

Каждая строка в файле, возможно, имеет переменное число десятичных цифровых символов, а не "одна строчка - одна циферка"


 
Palladin ©   (2007-12-26 16:54) [23]

ну млин :) прошу прощения, написал не то, что имел в виду
одна строчка - одно числеко


 
Сергей М. ©   (2007-12-26 16:57) [24]

Ну тады наверно так:

for i := 0 to SizeOf(MyRec)-0 do begin
 Readln(F, S);
 PByteArray(@MyRec)[i] := Byte(IntToStr(S));
end;


 
Сергей М. ©   (2007-12-26 16:59) [25]


> Ну тады наверно так:


Но при обязательном packed)


 
Сергей М. ©   (2007-12-26 17:00) [26]


> SizeOf(MyRec)-0


SizeOf(MyRec)-1


 
Palladin ©   (2007-12-26 17:01) [27]


> Byte(IntToStr(S));


так, ведь, приведение не обязательно, компилятор справится сам с этой задачей.. или я не прав? :)


 
Сергей М. ©   (2007-12-26 17:07) [28]


> Palladin ©   (26.12.07 17:01) [27]


Не суть как важно)
Это на случай потенциального overflow)


 
Sapersky   (2007-12-26 17:08) [29]

Но при обязательном packed)

В данном конкретном случае - не обязательно... хотя и вреда от него не будет.


 
Palladin ©   (2007-12-26 17:14) [30]

немножко будет, в случае array of MyRec


 
Anatoly Podgoretsky ©   (2007-12-26 17:21) [31]

> AlexanderMS  (26.12.2007 16:39:14)  [14]

Тебе нужен массив, а не запись.
И strtoint лишнее для Readln


 
Anatoly Podgoretsky ©   (2007-12-26 17:23) [32]

> Сергей М.  (26.12.2007 16:43:19)  [19]

Если не очевидно, то тогда программа полностью не работоспособная, смотри StrToInt(S)


 
Anatoly Podgoretsky ©   (2007-12-26 17:24) [33]

> Сергей М.  (26.12.2007 17:07:28)  [28]

> Это на случай потенциального overflow

Тогда опять программа неправильная и лучше получить сообщение об ошибке, чем неправильные данные и спрятаная ошибка.


 
Sapersky   (2007-12-26 18:12) [34]

немножко будет, в случае array of MyRec

Finally, the compiler rounds the total size of the record upward to the byte boundary specified by the largest alignment of any of the fields.
В данном случае это 1 байт, т.е. размер округляться не будет.



Страницы: 1 вся ветка

Текущий архив: 2008.01.27;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.011 c
2-1198657702
312kbps
2007-12-26 11:28
2008.01.27
Результат функции массив )


2-1199220887
DmT
2008-01-01 23:54
2008.01.27
Как получить доступ на чтение к переменной из другого юнита?


15-1198232337
destructor
2007-12-21 13:18
2008.01.27
У Google под колпаком?


2-1198876946
andreil
2007-12-29 00:22
2008.01.27
Помогите с написанием надстройки над ДЛЛкой!


2-1198744267
ilkz
2007-12-27 11:31
2008.01.27
StringList & Out of memory