IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Обмен информацией в файлах.
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Собственно,начал подзабывать язык,решил возродить.
Есть задача.
Даны 2 текстовых файла с произвольной информацией внутри,произвести обмен информацией,что бы в первом была инфа второго,во втором- первого.Использовать ренейм нельзя.Собственно идея такая,завести 3 файл и через него, как буфер(аналогично обмену 2 переменных).Собсвенно интересует,есть ли вобможность незаводя 3 файла сделать такую операцию?
И еще Readblock и wrihteblock смогут отработать с sizeof(file)?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Даны 2 текстовых файла с произвольной информацией внутри
Ну, текстовые-то они, если откроешь их как текстовые. Их ведь можно открыть и как file of byte, и как file of char... И как бестиповый в конце концов...

Цитата
Собсвенно интересует,есть ли вобможность незаводя 3 файла сделать такую операцию?
Собственно, почему бы и нет?

Ку? (Показать/Скрыть)


Цитата
И еще Readblock и wrihteblock смогут отработать с sizeof(file)?
sizeof(file) - это размер записи, представляющей информацию о файле, а не размер самого файла. Для получения размера файла - FileSize(f)... А Read/Writeblock работают с буфером. Какой выделишь - с тем и будут работать.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +



seek(f, posg); truncate(f);
seek(g, posf); truncate(g);


Как я понимаю идея такова,что происходит чтение и запись в начало файла,а потом транкейтом отрезается все,что после позиции, указывающей на конец другого файла?Интересненько.
Еще 2 таких вопроса.
seek(f, filepos(f) - sizeof(item));
это мы как раз и втыкаем наш символ перед первым символом в файле?
И зачем нужна процеруда write_file,разве мы не можем write_file(f, read_file(g)); сделать с обычным write?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Как я понимаю идея такова,что происходит чтение и запись в начало файла,а потом транкейтом отрезается все,что после позиции, указывающей на конец другого файла?
Да, если этого не сделать - то более короткий файл перезапишется данными из более длинного, тут все будет в порядке. А вот тот, что был длиннее - будет хранить "хвост" из своих старых данных. Его надо убрать. В принципе, нужен только один Truncate - для более длинного изначально файла.
Цитата
seek(f, filepos(f) - sizeof(item));
это мы как раз и втыкаем наш символ перед первым символом в файле?
Это мы после того, как прочли из файла очередную порцию данных (если интересно - покажу, как сделать это же самое с бестиповым файлом, там можно вычислить наибольший общий делитель размеров, для того, чтобы минимизировать число операций чтения/записи, не всегда читать побайтно), возвращается назад, чтоб потом ТУДА ЖЕ, откуда прочли, записать данные, считанные с другого файла.

Цитата
И зачем нужна процеруда write_file,разве мы не можем write_file(f, read_file(g)); сделать с обычным write?
Можем. Но выглядит лучше - когда процедуры "парные". blockread/blockwrite, read/write, readln/writeln... И тут я буду использовать read_file/write? Нет, не буду.

Сообщение отредактировано: IUnknown -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


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

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

Ну это уже принципи более менее понятно,т.к "порция" это абстрактная вещ.В текущем случае это char,а в бестипном, найдя НОД, будет nное кол-во байтов.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Ну это уже принципи более менее понятно
Хорошо... Понятно, говоришь? smile.gif Можно попросить тебя реализовать тот же самый алгоритм, но используя именно бестиповые файлы + НОД для того, чтобы (возможно) не читать байт за байтом, а читать максимально возможными порциями?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Зачем НОД? Почему мы берём именно фиксированный размер считываемой порции? Да можно сразу взять буфер на 64 килобайта и через него делать, а если после очередной считки буфер заполнился не до конца, то так и запомнить.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Зачем НОД? Почему мы берём именно фиксированный размер считываемой порции? Да можно сразу взять буфер на 64 килобайта и через него делать
Потому что МНЕ так хочется. Такой ответ устроит? Память - не резиновая, у меня НЕТ свободных 64К, чтобы прочесть в них 800 байт из файла.

Вот когда ты будешь писать - будешь делать так, как захочется тебе. Идея понятна?

Сообщение отредактировано: IUnknown -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Ну чтож я попытался,но не все так прекрасно вышло))))Мне почти удалось переписаль содержимое файлов друг в дружку за исключением пары ньюансов mad.gif

Хотя не, вру,еще чуть чуть и будет более менее пристойный вариант.

В общем оно вроде работает smile.gif

function nod(x,y : longint):longint;
begin
if x<>0 then nod:=nod( y mod x, x) else nod:=y;
end;

var
f, g :file;
b,p : string;
posf, posg :longint;
ser: longint;
begin
assign(f, '01.txt'); reset(f,sizeof(byte));
posf :=filesize(f);
assign(g, '02.txt'); reset(g,sizeof(byte));
posg :=filesize(g);
ser:=nod(posf,posg);

while not eof(f) and not eof(g) do
begin
BlockRead(f,b,Sizeof(byte)*ser);
seek(f,filepos(f)-Sizeof(byte)*ser);
BlockRead(g,p,Sizeof(byte)*ser);
seek(g,filepos(g)-Sizeof(byte)*ser);
BlockWrite(f,p,Sizeof(byte)*ser);
BlockWrite(g, b,Sizeof(byte)*ser);
end;

if eof(f) then
while not eof(g) do
begin
BlockRead(g,b,sizeof(byte));
Blockwrite(f, b,sizeof(byte));
end;
if eof(g) then
while not eof(f) do
begin
BlockRead(f, b,sizeof(byte));
BlockWrite(g, b,sizeof(byte));
end;

seek(f,posg); truncate(f);
seek(g,posf); truncate(g);

close(f); close(g);
end.


Не пинайте сильно,принципи можно было бы как то и свести к тому,что мне показывали,но как передать чтобы функция возвращала нужную мне длинну я хз)))реч о read_file : item;

P.S.Несмотря на то,что последняя строчка вне тегов кода,у меня почему то отображается внутри.

Сообщение отредактировано: Krjuger -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
  b,p : string;
// ...
BlockRead(f,b,Sizeof(byte)*ser);
Не делай так больше никогда. Ибо если размеры файлов будут кратны, друг другу, скажем, первый = 1010 байт, второй - 2020, то получишь "биг бада бум" (С) при попытке считать в строку (с максимальной длиной 255 символов) те же 1010 байт. Буфер надо выделять динамически. Кстати, когда будешь это делать - подумай над тем, что будет, если размер первого файла = 74184 байта, а второго - 222552 байт. Вот когда твоя программа будет отрабатывать и на таких файлах - тогда будем говорить дальше smile.gif Ты сам сказал, что
Цитата
Даны 2 текстовых файла с произвольной информацией внутри
, стало быть, размер файлов может быть тоже произвольным...



Сообщение отредактировано: IUnknown -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Память - не резиновая, у меня НЕТ свободных 64К, чтобы прочесть в них 800 байт из файла.

64K - для примера. Можно и 4K, или любое удобное число. Поиск числа, на которое делится размер файла, не имеет никакого смысла, кроме как для учебной задачи.

> Потому что МНЕ так хочется. Такой ответ устроит?

Типа как доп.задание? Ну ладно... Главное понимать, что это всего лишь учебное задание, а реального смысла в этом нет.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Цитата
Вот когда твоя программа будет отрабатывать и на таких файлах - тогда будем говорить дальше

А может лучше не надо дальше?)))
Я конешно постараюсь,что что то интузиазм угасает уже)

Цитата
Буфер надо выделять динамически

А тогда по какому принципу записывать в буфер информацию?Например у нас есть.

type
PerconPointer = ^PerconRecord;
PerconRecord = record
temp: string;
Next: PerconPointer
end;


В каждое поле записывать по 255 символов,либо temp будет чаром,но тогда мы недалеко уйдем от считывания по 1 байту.Получается что хоть у нас буфер и будет каким мы заходим,но его заполнение у меня упрется все равно в теже самые 255 символов,более того,если нельзя переписать сразу весь буфер(в данном случае я не знаю можно ли или нет) то наши труды будут весьма сомнительны.В общем то нужен вброс какой то информации,мои знания немного заканчиваются.

P.S.Если вспомнить откуда я брал задачку (методичка для 1 курса) то там решением задачи был бы самый первый код,дальше люди просто не проходили)

Сообщение отредактировано: Krjuger -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Динамический буфер делается не так.
Заводишь тип-указатель на массив максимально возможной длины (65534 байта), выделяешь для него нужное кол-во памяти через GetMem, потом, поработав с ним, освобождаешь через FreeMem


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


То есть нечто подобное

Buf : array of Char;
FSize : LongWord;
FSize := FileSize(F);
SetLength(Buf, FSize);
BlockRead(F,Pointer(Buf)^, FSize);


ну только собственно в FSize пишеться НОД.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Я думал, у тебя ТурбоПас.
Если у тебя Дельфи, то да, примерно так. Только SetLength(Buf, FSize) - это немного опрометчиво, файлы и на два гига бывают.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Заводишь тип-указатель на массив максимально возможной длины (65534 байта), выделяешь для него нужное кол-во памяти через GetMem, потом, поработав с ним, освобождаешь через FreeMem
лучше не превышать 65528:
Цитата(GetMem function)
Restrictions:
The largest block that can be safely allocated on the heap at one time is 65,528 bytes (64K-$8).
Если у кого-то и где-то один раз получилось выделить все 65534 - он может считать, что ему повезло. Гарантированно выделяется не больше 65528, все остальное зависит от фазы Луны и разных других факторов. В любом случае, для написания надежной программы не стоит обходить то, что написано в документации. Даже если очень хочется... Но на эту темя я уже говорил, повторяться не буду. Хотите обходить правила - обходите. Потом - не жалуйтесь!!!

Сообщение отредактировано: IUnknown -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Хорошо, пусть будет 65528. Параметры типа ни на что всё равно не влияют в данном случае.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Цитата

думал, у тебя ТурбоПас.
Если у тебя Дельфи, то да, примерно так.

У меня и то и то есть,но как сделать на турбо я вообще не знаю...Хотя сделать надо именно на турбо(
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Я же объяснил всё.

type
TBigArr = array [0 .. 65528] of byte;
PBigArr = ^TBigArr;

var
Buf: PBigArr;

...

GetMem(Buf, сколько надо);
...
работаем
...
FreeMem(Buf, сколько было надо, надо освободить ровно столько, сколько и заняли);



--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Что я делаю не так.

type
TArr= array [0..65528] of byte;
PArr = ^TArr;

function nod(x,y : longint):longint;
begin
if x<>0 then nod:=nod( y mod x, x) else nod:=y;
end;

var
f, g :file;
b,p : PArr;
posf, posg :longint;
ser: longint;

begin
assign(f, '01.txt'); reset(f,Sizeof(byte));
posf :=filesize(f);
assign(g, '02.txt'); reset(g,Sizeof(byte));
posg :=filesize(g);
ser:=nod(posf,posg);

while not eof(f) and not eof(g) do
begin
GetMem(b,ser);
GetMem(p,ser);
BlockRead(f,b,ser);
seek(f,filepos(f)-Sizeof(byte)*ser);
BlockRead(g,p,ser);
seek(g,filepos(g)-Sizeof(byte)*ser);
BlockWrite(f,p,ser);
BlockWrite(g,b,ser);
FreeMem(b,ser);
FreeMem(p,ser);
end;

GetMem(b,ser);
GetMem(p,ser);
if eof(f) then
while not eof(g) do
begin
BlockRead(g,b,sizeof(byte));
Blockwrite(f, b,sizeof(byte));
end;
if eof(g) then
while not eof(f) do
begin
BlockRead(f, b,sizeof(byte));
BlockWrite(g, b,sizeof(byte));
end;
seek(f,posg); truncate(f);
seek(g,posf); truncate(g);

dispose(b);
dispose(p);
close(f); close(g);
end.


На строчке FreeMem(b,ser); Invalid pointer operation.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.04.2024 3:15
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name