![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
Krjuger |
![]()
Сообщение
#1
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Собственно,начал подзабывать язык,решил возродить.
Есть задача. Даны 2 текстовых файла с произвольной информацией внутри,произвести обмен информацией,что бы в первом была инфа второго,во втором- первого.Использовать ренейм нельзя.Собственно идея такая,завести 3 файл и через него, как буфер(аналогично обмену 2 переменных).Собсвенно интересует,есть ли вобможность незаводя 3 файла сделать такую операцию? И еще Readblock и wrihteblock смогут отработать с sizeof(file)? |
IUnknown |
![]()
Сообщение
#2
|
![]() Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Ада: Разработчик Embarcadero Delphi: Сторонник Free Pascal: Разработчик Репутация: ![]() ![]() ![]() |
Цитата Даны 2 текстовых файла с произвольной информацией внутри Ну, текстовые-то они, если откроешь их как текстовые. Их ведь можно открыть и как file of byte, и как file of char... И как бестиповый в конце концов...Цитата Собсвенно интересует,есть ли вобможность незаводя 3 файла сделать такую операцию? Собственно, почему бы и нет?Ку? (Показать/Скрыть)
Цитата И еще Readblock и wrihteblock смогут отработать с sizeof(file)? sizeof(file) - это размер записи, представляющей информацию о файле, а не размер самого файла. Для получения размера файла - FileSize(f)... А Read/Writeblock работают с буфером. Какой выделишь - с тем и будут работать. |
Krjuger |
![]()
Сообщение
#3
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
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? |
IUnknown |
![]()
Сообщение
#4
|
![]() Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Ада: Разработчик Embarcadero Delphi: Сторонник Free Pascal: Разработчик Репутация: ![]() ![]() ![]() |
Цитата Как я понимаю идея такова,что происходит чтение и запись в начало файла,а потом транкейтом отрезается все,что после позиции, указывающей на конец другого файла? Да, если этого не сделать - то более короткий файл перезапишется данными из более длинного, тут все будет в порядке. А вот тот, что был длиннее - будет хранить "хвост" из своих старых данных. Его надо убрать. В принципе, нужен только один 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 - |
Krjuger |
![]()
Сообщение
#5
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Все теперь кажись окончательно понял,мы скидываем в буфер "порцию",затем затираем в исходном файле эту порцию порцией из другого файла и в другой записываем то,что из буфера.
Цитата если интересно - покажу, как сделать это же самое с бестиповым файлом, там можно вычислить наибольший общий делитель размеров, для того, чтобы минимизировать число операций чтения/записи, не всегда читать побайтно Ну это уже принципи более менее понятно,т.к "порция" это абстрактная вещ.В текущем случае это char,а в бестипном, найдя НОД, будет nное кол-во байтов. |
IUnknown |
![]()
Сообщение
#6
|
![]() Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Ада: Разработчик Embarcadero Delphi: Сторонник Free Pascal: Разработчик Репутация: ![]() ![]() ![]() |
Цитата Ну это уже принципи более менее понятно Хорошо... Понятно, говоришь? ![]() |
TarasBer |
![]()
Сообщение
#7
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Зачем НОД? Почему мы берём именно фиксированный размер считываемой порции? Да можно сразу взять буфер на 64 килобайта и через него делать, а если после очередной считки буфер заполнился не до конца, то так и запомнить.
-------------------- |
IUnknown |
![]()
Сообщение
#8
|
![]() Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Ада: Разработчик Embarcadero Delphi: Сторонник Free Pascal: Разработчик Репутация: ![]() ![]() ![]() |
Цитата Зачем НОД? Почему мы берём именно фиксированный размер считываемой порции? Да можно сразу взять буфер на 64 килобайта и через него делать Потому что МНЕ так хочется. Такой ответ устроит? Память - не резиновая, у меня НЕТ свободных 64К, чтобы прочесть в них 800 байт из файла. Вот когда ты будешь писать - будешь делать так, как захочется тебе. Идея понятна? Сообщение отредактировано: IUnknown - |
Krjuger |
![]()
Сообщение
#9
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Ну чтож я попытался,но не все так прекрасно вышло))))Мне почти удалось переписаль содержимое файлов друг в дружку за исключением пары ньюансов
![]() Хотя не, вру,еще чуть чуть и будет более менее пристойный вариант. В общем оно вроде работает ![]()
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 - |
IUnknown |
![]()
Сообщение
#10
|
![]() Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Ада: Разработчик Embarcadero Delphi: Сторонник Free Pascal: Разработчик Репутация: ![]() ![]() ![]() |
Цитата b,p : string;
// ...
BlockRead(f,b,Sizeof(byte)*ser);
![]() Цитата Даны 2 текстовых файла с произвольной информацией внутри , стало быть, размер файлов может быть тоже произвольным...Сообщение отредактировано: IUnknown - |
TarasBer |
![]()
Сообщение
#11
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Память - не резиновая, у меня НЕТ свободных 64К, чтобы прочесть в них 800 байт из файла.
64K - для примера. Можно и 4K, или любое удобное число. Поиск числа, на которое делится размер файла, не имеет никакого смысла, кроме как для учебной задачи. > Потому что МНЕ так хочется. Такой ответ устроит? Типа как доп.задание? Ну ладно... Главное понимать, что это всего лишь учебное задание, а реального смысла в этом нет. -------------------- |
Krjuger |
![]()
Сообщение
#12
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Цитата Вот когда твоя программа будет отрабатывать и на таких файлах - тогда будем говорить дальше А может лучше не надо дальше?))) Я конешно постараюсь,что что то интузиазм угасает уже) Цитата Буфер надо выделять динамически А тогда по какому принципу записывать в буфер информацию?Например у нас есть.
type
PerconPointer = ^PerconRecord;
PerconRecord = record
temp: string;
Next: PerconPointer
end;
В каждое поле записывать по 255 символов,либо temp будет чаром,но тогда мы недалеко уйдем от считывания по 1 байту.Получается что хоть у нас буфер и будет каким мы заходим,но его заполнение у меня упрется все равно в теже самые 255 символов,более того,если нельзя переписать сразу весь буфер(в данном случае я не знаю можно ли или нет) то наши труды будут весьма сомнительны.В общем то нужен вброс какой то информации,мои знания немного заканчиваются. P.S.Если вспомнить откуда я брал задачку (методичка для 1 курса) то там решением задачи был бы самый первый код,дальше люди просто не проходили) Сообщение отредактировано: Krjuger - |
TarasBer |
![]()
Сообщение
#13
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Динамический буфер делается не так.
Заводишь тип-указатель на массив максимально возможной длины (65534 байта), выделяешь для него нужное кол-во памяти через GetMem, потом, поработав с ним, освобождаешь через FreeMem -------------------- |
Krjuger |
![]()
Сообщение
#14
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
То есть нечто подобное
Buf : array of Char;
FSize : LongWord;
FSize := FileSize(F);
SetLength(Buf, FSize);
BlockRead(F,Pointer(Buf)^, FSize);
ну только собственно в FSize пишеться НОД. |
TarasBer |
![]()
Сообщение
#15
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Я думал, у тебя ТурбоПас.
Если у тебя Дельфи, то да, примерно так. Только SetLength(Buf, FSize) - это немного опрометчиво, файлы и на два гига бывают. -------------------- |
IUnknown |
![]()
Сообщение
#16
|
![]() Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Ада: Разработчик Embarcadero Delphi: Сторонник Free Pascal: Разработчик Репутация: ![]() ![]() ![]() |
Цитата Заводишь тип-указатель на массив максимально возможной длины (65534 байта), выделяешь для него нужное кол-во памяти через GetMem, потом, поработав с ним, освобождаешь через FreeMem лучше не превышать 65528:Цитата(GetMem function) Restrictions: Если у кого-то и где-то один раз получилось выделить все 65534 - он может считать, что ему повезло. Гарантированно выделяется не больше 65528, все остальное зависит от фазы Луны и разных других факторов. В любом случае, для написания надежной программы не стоит обходить то, что написано в документации. Даже если очень хочется... Но на эту темя я уже говорил, повторяться не буду. Хотите обходить правила - обходите. Потом - не жалуйтесь!!!The largest block that can be safely allocated on the heap at one time is 65,528 bytes (64K-$8). Сообщение отредактировано: IUnknown - |
TarasBer |
![]()
Сообщение
#17
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Хорошо, пусть будет 65528. Параметры типа ни на что всё равно не влияют в данном случае.
-------------------- |
Krjuger |
![]()
Сообщение
#18
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Цитата думал, у тебя ТурбоПас. Если у тебя Дельфи, то да, примерно так. У меня и то и то есть,но как сделать на турбо я вообще не знаю...Хотя сделать надо именно на турбо( |
TarasBer |
![]()
Сообщение
#19
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Я же объяснил всё.
type
TBigArr = array [0 .. 65528] of byte;
PBigArr = ^TBigArr;
var
Buf: PBigArr;
...
GetMem(Buf, сколько надо);
...
работаем
...
FreeMem(Buf, сколько было надо, надо освободить ровно столько, сколько и заняли);
-------------------- |
Krjuger |
![]()
Сообщение
#20
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Что я делаю не так.
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. |
![]() ![]() |
![]() |
Текстовая версия | 20.04.2025 7:39 |