Помощь - Поиск - Пользователи - Календарь
Полная версия: Как создать типизированный файл
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
kosya4ok
Всем привет! Почитал про типизированные файлы на форуме но так и не наашёл решение своей проблемы.
Хочу создать типизированный файл в который будут писать числа типа real.


const n = 8;
{type numbers = record
num : real;
end;}
type numbers = file of real;
var fname : string;
i : integer;
sum, k : real;
ans : char;
f1 : numbers;

function fi(p: integer): real;
var i : integer;
sum : real;
begin

sum := sqrt(3 * p);
for i := p downto 1 do
if (i = 1) then
fi := sum
else
sum := sqrt(sum + 3 * (i - 1));
end;

procedure newfile(var f1 : numbers);
var s : string;
num : real;
{with num_ref do}
begin
rewrite(f1);
{write(f1, num_ref);}
for i := n downto 1 do
begin
if (i = 1) then
begin
num := sqrt(3);
writeln(f1, num);
break;
end
else
begin
writeln(f1, fi(i));
end;
end;
close(f1);
end;

procedure outputfile(var f1 : numbers; p : integer);
var s : string;

begin
reset(f1);
repeat
readln(f1, s);
write('f', p, '=');
writeln(s);
dec(p);
until eof(f1);
end;

begin
clrscr;
writeln('Create a new file?');
readln(ans);
ans := upcase(ans);
if (ans = 'Y') or (ans = 'YES') then
begin
writeln('Enter name a file');
readln(fname);
assign(f1, fname);
newfile(f1);
outputfile(f1, n);
end
else
begin
writeln('What file you want open?');
readln(fname);
assign(f1, fname);
outputfile(f1, n);
end;
readln;
end.



Пишет инвалидный тип файла. Помогите разобраться...
volvo
Данные в типизированный файл не пишутся через WriteLn, только через Write...
kosya4ok
Ага. volvo заменил writeln на write, но только теперь почему то на консоль выводит то что мне надо, а вот в файле абракадабра получается blink.gif
Вот такой отредактированный код.

const n = 8;
type numbers = file of real;
var fname : string;
sum, k : real;
ans : char;
f1 : numbers;

function fi(var p: integer): real;
var i : integer;
sum : real;
begin

sum := sqrt(3 * p);
for i := p downto 1 do
if (i = 1) then
fi := sum
else
sum := sqrt(sum + 3 * (i - 1));
end;

procedure newfile(var f1 : numbers);
var s : string;
num : real;
i : integer;
begin
rewrite(f1);
for i := n downto 1 do
begin
if (i = 1) then
begin
num := sqrt(3);
write(f1, num);
break;
end
else
begin
num := fi(i);
write(f1, num);
{write(f1, fi(i));}
end;
end;
close(f1);
end;

procedure outputfile(var f1 : numbers; p : integer);
var s : real;
begin
reset(f1);
repeat
read(f1, s);
write('f', p, '=');
writeln(s);
dec(p);
until eof(f1);
end;

begin
clrscr;
writeln('Create a new file?');
readln(ans);
ans := upcase(ans);
if (ans = 'Y') or (ans = 'YES') then
begin
writeln('Enter name a file');
readln(fname);
assign(f1, fname);
newfile(f1);
outputfile(f1, n);
end
else
begin
writeln('What file you want open?');
readln(fname);
assign(f1, fname);
outputfile(f1, n);
end;
readln;
end.



Это вывод на консоль.
[IMG]http://ipicture.ru/uploads/071214/TWOsF6aW2Z.JPG[/IMG]
А это что в файле.

‚WХA‚шй3‚cэ¬‚^п
‚-!Фж‚I pД‚Жд
gЃГBЧі]
volvo
Цитата
а вот в файле абракадабра получается
А вот смотреть блокнотом не надо типизированные файлы, они содержат не символьное представление информации (как текстовые), а битовое, машинное представление... То есть, просто берется кусок из памяти и пишется в файл (в твоем случае - 6 байт, посмотри что там хранится - поиск по слову IEEE), а Блокнот думает что там записаны байтовые коды символов... Представляешь, как он жестоко ошибается? smile.gif

Читать типизированный файл надо опять же в программой на Паскале - тогда память опять заполнится правильно (если тип файла совпадает), и ты получишь разумные данные...
kosya4ok
Так я так и не понял что надо сделать то? unsure.gif
Как тогда надо записать данные в файл что бы можно было посмотреть блокнотом или ещё чем то? Или в блокноте просто надо опции какие то поменять? Или надо поставить другое расширение файла?
volvo
Цитата
Как тогда надо записать данные в файл что бы можно было посмотреть блокнотом
Значит, надо создавать НЕ типизированный, а текстовый файл. Блокнот (или еще что-нибудь) - это текстовый редактор.
kosya4ok
Окей. А чем посмотреть тогда типизированный файл или как записать типизированный файл что бы можно ьбыло его посмотреть?
andriano
Типизированный файл при желании можно посмотреть hex-редактором. Что ты там сможешь понять - это другое дело.
Но, вообще-то, для просмотра предназначен как раз текстовый формат, а типизированный файл принципиально не предназначен для того, чтобы его смотреть глазами.
Ты уж вибери, что тебе надо: типизированный или смотреть.
kosya4ok
Ясно. Спасибо за понятный ответ. А то народ никак не может внятно объяснить с этим типизированным файлом.
volvo
dry.gif Сколько же можно тебе объяснять? Тебе поста №4 не хватило, чтобы догадаться зайти в Google и набрать IEEE? И посмотреть, ЧТО будет храниться в файле? Почему все время надо с ложечки кормить?
kosya4ok
Так а сколько ты нормально раз объснял?Покажи. Зашёл и набрал IEEE вот чё вывалило

www.ieee.org
ieeexplore.ieee.org
www.computer.org
www.spectrum.ieee.org и т.д. в таком же духе

И интересно какую можно из этого всего извлечь информацию? И причём здесь ложечки кормить?
Почему не ответить так что бы больше не возникало вопросов, а отвечаешь так что больше вознкиает вопросов чем ответов?

Лано, буду тему закрывать так как всё в принципе выянил. Всем кто участвовал спасибо за помощь.
andriano
Вдогонку: чем смотреть типизированный файл?
Специальным написанным тобой просмотрщиком, ориентированным на файлы заданногоо тобой типа. Этот просмотрщик должен читать из файла бинарные данные, преобразовывать их в текст и этот текст показывать тебе на экране. (а, может, - преобразовывать в графику и показывать изображение... Смотря для чего задумывался такой тип файла)

PS. А по поводу ссылок тебе все правильно сказали. Информацию можно извлечь как раз о том, как следует группировать и интерпретировать те коды, которые ты безуспешно пытался просмотреть текстовым редактором.

PPS. Да, volvo, я что-то запамятовал, правда ли, что 6-байтовый real действительно стандартизован? Мне казалось, что стандартизованы только single и double, а real - частный формат, ориентированный на обработку без FPU.
kosya4ok
Я не понимаю как мона сгруппировать и извлечь информацию из данного типизированного файлас помощью блокнота или ещё чего то там. Мона показать пример?

ЗЫ Не понял, всмысле просмотрщик файла?Ведь у меня функция и выводит бинарные данные из файла, но только на консоль.


procedure outputfile(var f1 : numbers; p : integer);
var s : real;
begin
reset(f1);
repeat
read(f1, s);
write('f', p, '=');
writeln(s);
dec(p);
until eof(f1);
end;



Или ты что то другое имеел ввиду?
volvo
Цитата
правда ли, что 6-байтовый real действительно стандартизован? Мне казалось, что стандартизованы только single и double, а real - частный формат, ориентированный на обработку без FPU.
mega_chok.gif

32-битные компиляторы не доведут до добра. Привычка, что real = double... Ну, а по поводу формата 6-байтного real - в частности можно посмотреть здесь: http://de.uspu.ru/Informatics/Metodes/DPP/...glavs/4/433.htm
andriano
Цитата(kosya4ok @ 14.12.2007 21:04) *

Я не понимаю как мона сгруппировать и извлечь информацию из данного типизированного файлас помощью блокнота или ещё чего то там. Мона показать пример?
С помощью блокнота - никак.
Точка.
(кажется, тебе это повторили уже 3 раза)
Цитата

ЗЫ Не понял, всмысле просмотрщик файла?Ведь у меня функция и выводит бинарные данные из файла, но только на консоль.
А твоя программа и есть простенький консольный просмотрщик типизированного файла. Т.е. для просмотра такого файла нужно пользоваться ею ВМЕСТО блокнота.


Добавлено через 9 мин.
Цитата(volvo @ 14.12.2007 21:16) *
32-битные компиляторы не доведут до добра. Привычка, что real = double...
С чего это вдруг?
Последние несколько лет пользуюсь ТОЛЬКО 32-разрядными компиляторами и никакого "недобра" еще не почувствовал.
Может, я что-то не так делаю?

Кстати, real вообще НИКОГДА не использую.
И еще: real = double связано все-таки не с 16- или 32-разрядностью, а с тем, что к моменту появления этих 32-разрядных FPU стал непременным атрибутом ЛЮБОГО компьютера, т.к. переселился внутрь CPU. Соответственно, надобность в real, оптимизированном на обработку CPU, отпала. А на FPU он обсчитывается заметно дольше, чем поддерживаемые аппаратно single или double.
Цитата
Ну, а по поводу формата 6-байтного real - в частности можно посмотреть здесь: http://de.uspu.ru/Informatics/Metodes/DPP/...glavs/4/433.htm

Посмотрел.
Ничего для себя интересного не обнаружил.
Я спрашивл: стандартизирован ли 6-байтовый real, или это исключительно "местное" изобретение Борланд?
Даже в 48-разрядной БЭСМ-6 формат представления вещественных данных (т.е. той же длины - 6 байт) был другим.
kosya4ok
Цитата(kosya4ok @ 14.12.2007 21:04)

Я не понимаю как мона сгруппировать и извлечь информацию из данного типизированного файлас помощью блокнота или ещё чего то там. Мона показать пример?
С помощью блокнота - никак.
Точка.
(кажется, тебе это повторили уже 3 раза)

Вот блин народ! Та я понял что с помощью блокнота что не смогу! Я ж спрашиваю как можно сгруппировать эти символы без блокнота, так как вы сами мне об этом написали!
andriano
Группировать по 6 байтов (48 битов).
А что конкретно означают какие биты - по тем ссылакам, что тебе дал поисковик.
Гость
СПС всем !!ТЕМА закрыта!
kosya4ok
А вы не объясните почему вот так вот можно писать в файл


num := fi(i);
write(f1, num);



А вот так вот нельзя.


num := fi(i);
write(f1, fi(i));

Lapp
Цитата(kosya4ok @ 14.12.2007 23:43) *

А вы не объясните почему ... вот так вот нельзя.
write(f1, fi(i));

Грубо говоря, параметры оператора Write всегда передаются по адресу (по ссылке). Функция - это сложная структура, которая предусматривает передачу управления и возвращение значения. Когда ты пишешь так, то ты на самом деле как бы указываешь оператору Write адрес перехода, хотя он ожидает адрес той области памяти, которую тебе надо вывести на печать. Если бы компилятор не отловил ошибку, ты бы получил на печати совсем не то, что ожидал smile.gif.
Это был образный ответ, упрощенный. На самом деле все сложнее, конечно. Но в случае с типизированными файлами довольно близко к действительности.
andriano
kosya4ok,
просмотрел тему и у меня сложилось впечатление, что некоторое недопонимание между тобой и теми, кто тебе отвечал связано тем, что тебе нужно разобрать ДВА вопроса, а не ОДИН:
1. Чем отличается бинарное (внутреннее, машинное) редставление чисел от текстового (форматного).
2. Для чего нужен типизированный файл.

1. Внутри компьютера числа находятся в бинарном виде. Так же они могут быть и сохранены на диске. Т.е. область диска (файл) может быть просто копией фрагмента оперативной памяти. Но разобрать что-либо в таком файле глазами совершенно невозможно. Поэтому прибегают к текстовому представлению информации. При этом дробное число, занимающее в памяти (или бинарном файле), скажем, 4 байта, в виде текста займет уже 12 байт - да и то с потерей точности. Опять же, Паскаль скрывает этот факт, но операторы read и write с текстовыми и бинарными файлами работают совершенно по-разному: при работе с текстом каждый символ подвергается достаточно сложным преобразованиям. Таким образом, разработчику всеегда риходится решать, какому формату файла отдать предпочтение в конкретной программе.
Если нам надо хранить, скажем, 8 Мбайт данных, то
- бинарное представление: длина файла - 8 Мбайт, время чтения - 0.1 с, глазами ничего не увидишь,
- текстовое представление: длна файла - 96 Мбайт, время чтения - 50 с, можно посмотреть глазами.
Что ты в данном случае предпочтешь?
А если надо записать всего десяток чисел, которые и в том, и в другом случае будут занимать один сектор на диске и читаться практически мгновенно?

2. Вообще-то он не нужен. Т.е. без него легко можно обойтись, заменив файлом нетипизированным. Но в некоторых случаях удобнее работать с типизированным.
Твой пример к таковым не относится: если ты работаешь с вещественными числами, то разницы между типизированным и нетипизированным практически нет.
А когда же появляется разница?
Тогда, когда тебе нужно работать не с простым, а со сложным типом данных. Ну например:
type
t3DPoint = packed record
x,y,z : single; // координаты точки в пространстве
u,v : byte; // текстурные координаты
end;

Длина такого типа данных составляет 14 байт и, чтобы не запутаться, лучше объявить фвйл как file of t3DPoint. Одновременно, если ты запросишь длину файла, то тебе будет возвращено именно количество точек, а не количество байтов.
kosya4ok
Опочки прикольно! То есть вы хотите сказать что write принимает типа write(&, &), а ему даю write(&, ЗНАЧЕНИЕ ОБЛАСТИ ПАМЯТИ) Так? Я с указателями в Паскале пока ещё не разбирался и плохо пока знаю эту тему. А можно тогда в Паскале перегрузить оператор write что бы он принимал write(&, ЗНАЧЕНИЕ)?
andriano
Минуточку.
Та ЗНАЧЕНИЕ или ОБЛАСТЬ ПАМЯТИ?
write работает именно с областью памяти. А результат функции возвращается в регистрах процессора. Поэтому, естественно, у него нет АДРЕСА и write не может с ним работать.
По поводу пергрузки: во-первых, write - не функция, а во вторых: "а оно надо?".

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

procedure proc1(a : integer);
begin
inc(a);
end;

procedure proc2(var a : integer);
brgin
inc(a);
end;

var i1,i2 : integer;
begin
i1 := 10;
i2 := 20;
writeln(i1:4,i2:4);
proc1(i1);
proc2(i2);
writeln(i1:4,i2:4);
proc1(30);
proc2(40);
end.
kosya4ok
Привет! Вот же ж люди какие бывают какие проницательные! Извиняюсь за свою не точную формулировку данной задачи, больше буду работать над собой.

Если нам надо хранить, скажем, 8 Мбайт данных, то
- бинарное представление: длина файла - 8 Мбайт, время чтения - 0.1 с, глазами ничего не увидишь,
- текстовое представление: длна файла - 96 Мбайт, время чтения - 50 с, можно посмотреть глазами.
Что ты в данном случае предпочтешь?

Конечно же я предпочел увидеть собственными глазами + время чтения 0.1 с good.gif

Поповоду кода. Если я сделаю так sizeof(t3Dpoint), то будут 14 байт.
А если так type f1 = file of t3Dpoint, то sizeof(f1), то будут 128 что? Байт?И как это соотнесется с точками?

С количеством точек и числом байтов, что то не совсем понятно. Можно пример?
andriano
Длина файла возвращается в количестве тех переменных указанного типа, что ты описал. Т.е. если в файле присутствует 100 14-байтных записей (точек), то FileSize(F) возвратит число 100. Длина же файла при этом составит 1400 байт.
Функция же sizeof возвращает не длину файла, а размер объекта в байтах. т.е. для одной точки это будет 14.

Цитата
А если так type f1 = file of t3Dpoint, то sizeof(f1), то будут 128 что? Байт?И как это соотнесется с точками?
Это будет длина перемнной типа f1 в байтах. К длине файла она никакого отношения не имеет. Ведь, обрати внимание, ее тип не "3DPoint", а "File of 3DPiont", а это далеко не одно и то же.
Просто тип file - это тоже сложный тип, состоящий из нескольких полей, в которых хранится набор переменных, необходимых для доступа к файлу. С содержимым файла содержимое этих переменных никак не связано.
Если проводить аналогию, то файл и файловая переменная связаны примерно так же, как ячейка памяти и указательна ячейку памяти.
kosya4ok
За

По поводу пергрузки: во-первых, write - не функция, а во вторых: "а оно надо?".

Сорри пока не выучил терминоголию, конечно не функция, а процедура. А вопрос был задан с целью экстеншена данной программки. Думал просто провести аналогия с cout.

Просто тогда write отложу пока в сторону пока не разберусь с разлиными передачами в процедуры и функции.


procedure proc1(a : integer);
begin
inc(a);
end;

procedure proc2(var a : integer);
brgin
inc(a);
end;

var i1,i2 : integer;
begin
i1 := 10;
i2 := 20;
writeln(i1:4,i2:4);
proc1(i1);
proc2(i2);


Я так понимаю произошла передача переменных по ссылке?
Так а так

proc1(30);
proc2(40);


неполучится, т.к. низя ж передавать в процедуру константное выражение, а только адрес переменной?
andriano
Нет, в том то и дело, что в proc1 произошла передача значения, а в proc2 - адреса (т.е. "по ссылке"), хотя внешне код выглядит совершенно одинаково.
А что касается "не получится", то первая строка омпилируется, т.к. константа (содержащаяся в сегменте кода, если это о чем-то говорит) при вызове записывается в стек, а во втором случае в стек должен быть записан адрес, но в сегменте данных этой константы нет, соответственно, нет и адреса. Вот компилятор и отказывается пропускать эту строку.
kosya4ok
Ну и ну. Вообщем пошёл учить Паскаль.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.