Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Работа с файлами...

Автор: Akella 26.11.2008 19:58

Короче задание такое: Создать файл, заполненный целочисленными яислами в диапозоне [-100;100]. Удалить из файла все положительные числа!

У меня короче получаеться вот что: ввожу например 5, т.е. это генирируется 5 чисел. И получается что действие происходит только над четными элементами файла(начиная с 0-го). Например есть числа -10 -11 10 10 -15, то в результате останеться -10 и -15, а -11 куда-то пропадает... помогите... что я только не перепробывал сделать - не получается!

program  _7_14;    
uses crt;
var f : file of integer;
i,n,a : integer;
begin clrscr;
randomize;
assign(f,'myfile.dat');
rewrite(f);
writeln('n=');
read(n);
for i:=1 to n do begin
a:=random(200)-100;
write(f,a);
end;
seek(f,0);
while not eof(f) do begin
read(f,a);
write(a,' ');
end;
seek(f,0);
while not eof(f) do begin
read(f,a);
if a>0 then seek(f,filepos(f)+1)
else begin
write(f,a);
writeln(a,' ');
end;
end;
end. close(f);
end.

Автор: Unconnected 26.11.2008 20:18

Мне кажется,тут лучше использовать тип text.

Автор: volvo 26.11.2008 20:19

Цитата
И получается что действие происходит только над четными элементами файла(начиная с 0-го)
Угу... А почему - сам виноват:
while not eof(f) do begin
read(f,a);
if a>0 then seek(f,filepos(f)+1) { <--- Вот тут ошибка }
else begin
write(f,a);
writeln(a,' ');
end;
end;

(ты уже прочел число из файла, значит указатель передвинулся на следующий элемент автоматически. Зачем ты передвигаешь его еще дальше? Ну, и потом... Тебе надо не напечатать все числа, кроме положительных, а удалить положительные из файла. Этого ты даже не пытаешься сделать... А нужно для этого всего навсего завести еще одну переменную LastNeg, которая будет хранить смещение последнего правильного НЕположительного числа в файле. Идешь дальше, как только встретил очередное отрицательное - записал его на эту, сохраненную позицию и увеличил ее на 1... А в самом конце - Truncate(LastNeg), чтобы отсечь все лишнее)

Кстати, у тебя файл не закрывается... Предпоследнего End-а не должно быть...

Добавлено через 1 мин.
Цитата
Мне кажется,тут лучше использовать тип text.
С чего бы? Чтоб места занимал больше? Или потому что кто-то не умеет работать с ДРУГИМИ файлами? Мне вот вообще кажется, что на другом языке эта задача решается проще, и что? Это не повод советовать автору писать не на Паскале...

Автор: Akella 26.11.2008 20:37

Цитата(volvo @ 26.11.2008 23:19) *

завести еще одну переменную LastNeg, которая будет хранить смещение последнего правильного НЕположительного числа в файле.

что-то я вот это предложение не понял=)) особенно " хранить смещение последнего правильного НЕположительного числа в файле"....

Автор: volvo 26.11.2008 21:24

Смотри:

{ ... заполнил файл ... }
reset(f); { Перешел на начало файла }

LastNeg := -1; { Самое начало, еще не было обработано ничего }
while not eof(f) do begin
read(f, a); { Читаем очередное число из файла }
if a < 0 then begin { Отрицательное ? }
CurrPos := FilePos(f); { Это нам и надо: запоминаем, где мы БЫЛИ. Продолжать будем отсюда же }
inc(LastNeg); { Увеличиваем счетчик отрицательных чисел ... }
Seek(f, LastNeg); { ... и переходим на ту позицию, куда очередное число должно быть записано }
write(f, a); { Собственно, записываем число }
Seek(f, CurrPos); { И возвращаемся туда, где были, чтобы продолжить сканировать файл }
end;
end;

Seek(f, LastNeg + 1); { А теперь устанавливаем указатель за последним отрицательным числом }
Truncate(f); { ... и "отсекаем" хвост }
reset(f); { Для сохранности данных... Да и вообще, потом надо печатать содержимое файла }


Автор: Akella 29.11.2008 19:39

огромное спасибо, все понятно мне разжевали....

Автор: Akella 2.12.2008 15:52

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

Автор: volvo 2.12.2008 16:04

Каких цифр? У тебя нет никаких цифр, у тебя есть числа, представленные НЕ текстом, а двоичным кодом (машинное представление). Что именно тебе надо посчитать?

Автор: Akella 2.12.2008 16:10

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

close(f);    
assign(g,'myfile.dat');
reset(g,bufsize);
blockread(g,buf,bufsize);


у меня 1-й вопрос: какими типами должны быть переменные? (buf,bufsize)

ВОТ! Нашел как звучит задание! Найти конечную сумму полученного файла, открыв его как нетипизированный!
p.s. открой аську плиз=)

Автор: volvo 2.12.2008 16:23

Повторяю: числа не зашифрованы ничем. Это просто последовательность бит. К примеру, число 25 представлено так: 0000000000011001, а число 126 - так: 0000000001111110. Так что, говоришь, найти-то надо?

Автор: Akella 2.12.2008 16:32

ВОТ задание так в карточки написано:
Найти конечную сумму полученного файла, открыв его как нетипизированный!

Автор: volvo 2.12.2008 16:41

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

var
g: file;
sum, X: integer;

{ ... }

assign(g, 'myfile.dat');
reset(g, sizeof(integer)); { <--- открываешь файл с размером буфера = размеру integer-а }
sum := 0;
while not eof(g) do begin
blockread(g, X, 1); { <--- читаем блок, соответствующий следующему числу, в X }
sum := sum + X; { <--- и добавляем к сумме }
end;
{ все, сумма подсчитана, выводим }

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

Автор: Akella 2.12.2008 16:42

я так делал, но у меня ошибка 200... что это такое?
вот готовая прога, все работает... спасибо Volvo

program  _7_14;    

uses crt;
var
f : file of integer;
g : file;
i,n,a,CurrPos,LastNeg,sum,buf : integer;

begin
clrscr;
randomize;
assign(f,'myfile.dat');
rewrite(f);
write('n=');
read(n);
for i:=1 to n do begin
a:=random(200)-100;
write(f,a);
end;
seek(f,0);
while not eof(f) do begin
read(f,a);
write(a,' ');
end;
reset(f);
LastNeg := -1;
while not eof(f) do begin
read(f, a);
if a < 0 then begin
CurrPos := FilePos(f);
inc(LastNeg);
Seek(f, LastNeg);
write(f, a);
Seek(f, CurrPos);
end;
end;
Seek(f, LastNeg + 1);
Truncate(f);
reset(f);
gotoxy(1,5);
while not eof(f) do begin
read(f,a);
write(a,' ');
end;
close(f);
assign(g,'myfile.dat');
reset(g,sizeof(integer));
sum:=0;
while not eof(g) do begin
blockread(g,buf,1);
sum:=sum + buf;
end;
gotoxy(1,10);
write(sum);
end.

Автор: Ozzя 2.12.2008 16:52

Help (Ctrl + F1) по слову blockread Вам окажет неоценимую помощь.

Добавлено через 3 мин.
Обнови tpl'ки - http://pascal.sources.ru/misc/bp7_tpl.htm

Автор: Akella 16.12.2008 18:19

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

Автор: volvo 16.12.2008 18:49

Цитата
3 часа бьюсь, только паскаль зависает
Значит, что-то начал делать? Можно посмотреть, как именно ты начал решать задачу?

Автор: Akella 16.12.2008 18:56

прога зависала из-за условия, потому что оно зацикливалось, поэтому я его удалил, а все остальное как в проге выше!

Автор: volvo 16.12.2008 20:22

Akella, смотри как это делается:

var
f: file of integer;
i, X, Y: integer;
pos, curr: longint;
found: boolean;

begin
assign(f, 'test.dat'); rewrite(f);

{ Запрашиваем данные у пользователя и пишем в файл }
for i := 1 to 10 do begin
write(i:2, ' -> '); readln(X);
write(f, X);
end;

reset(f); pos := 0; { переоткрываем файл и начинаем с самого начала }
while not eof(f) do begin
read(f, X); { прочитали число }
curr := filepos(f); { запомнили, где были в файле }
seek(f, 0); { идем в самое начало }

found := false;

{ и пока не добрались до позиции, в которую записали последнее число }
while filepos(f) < pos do begin
read(f, Y); { Читаем ранее записанные числа, и ищем среди них X }
if Y = X then found := true;
end;
if not found then begin { X не был найден }
{ Значит, пишем его в файл в позицию Pos, и увеличиваем Pos на 1 }
seek(f, pos); write(f, X); inc(pos);
end;
seek(f, curr); { Возвращаемся туда, где остановились, и продлолжим просматривать файл }
end;

{ Все, весь файл пересмотрен, записано Pos чисел, остальные - дубликаты }
seek(f, pos);
{ Отсекаем эти дубликаты }
truncate(f);

{ Проверка, получилось ли то, что задумывалось }
reset(f);
while not eof(f) do begin
read(f, X); write(X:3);
end;
writeln;
close(f);
end.


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

Автор: Akella 18.12.2008 18:03

спасибо, но мне чуток по другому надо, повторяющиеся цифры вообще не должны потом выводиться=)

Автор: Akella 19.12.2008 16:49

Помогите, что я не правильно написал? wacko.gif Задача такая: В последовательность K вещ. чисел на позицию N вставить число M, следущие за M числа сдвинуть на N+1, N+2 и т.д., т.е.
0.123 0.123 .123 0.123 на позицию 1(считая с нуля) поставим число 1.234 - получим:
0.123. 1.234 0.123 0.123 0.123

program  _7_1;   

uses crt;

var f : file of real;
g : file;
N,K,sum,buf,i,kurpos : integer;
M,x,y,z : real;

begin
clrscr;
randomize;
assign(f,'myfile.dat');
rewrite(f);
write('vvedite kolichestvo sluchainih chisel K=');
readln(K);
for i:=1 to K do begin
x:=random;
write(f,x);
end;
write('vvedite chislo M=');
readln(M);
write('vvedite poziciu zameni N=');
readln(N);
seek(f,0);
writeln('sluchainie chisla');
while not eof(f) do begin
read(f,x);
write(x:2:3,' ');
end;
reset(f);
seek(f,N);
read(f,x);
y := x;
seek(f,N);
write(f,M);
while not eof(f) do begin
kurpos := FilePos(f);
read(f, x);
z := x;
seek(f,kurpos);
write(f,y);
seek(f,kurpos);
y := z;
end;
{ Seek(f, ); Truncate(f);}
reset(f); gotoxy(1,7); write('posle udaleniya polojitelnih chisel'); gotoxy(1,9);
while not eof(f) do begin
read(f,x);
write(x:2:3,' ');
end;
close(f);
end.

Автор: volvo 19.12.2008 17:25

После того как записал в файл все нужные тебе числа, лучше сделать так:

  reset(f);
seek(f,filesize(f));

X := 0; write(f, X); { <--- Пишем 0 в самый конец файла, увеличивая его размер }
seek(f, filepos(f) - 2); { <--- Устанавливаем указатель на число, с которого начнем перемещение }
{ Это как раз то самое число, которое было последним в файле, }
{ пока туда не записали 0 }

{
А дальше - все просто: читаем число, при этом указатель сам перемещается
на следующую позицию в файле, туда прочитанное число и пишем, указатель
опять перемещается еще дальше, а мы его перебрасываем на 3 (!!!) позиции
назад, чтобы на следующем круге начать перемещение на одну позицию раньше.

Повторять, пока не дойдем до нужной позиции
}
while filepos(f) >= N do begin
read(f, x); write(f, x);
seek(f, filepos(f) - 3);
end;

seek(f, N); write(f, M); { Все, пишем туда куда надо введенное число }
{ И выводишь файл на печать для проверки }


Автор: Akella 19.12.2008 19:02

ааааааааааааа я понял, блин я даже и не додумался с конца начать=))

Автор: Akella 19.12.2008 20:23

извините за оформление(торопился). Вопрос: почему не считает контрольную сумму получившихся элементов? Не понимаю, в другой программе все работало....

uses crt;
var f: file of integer;
g : file;
i, X, Y, N, buf, sum: integer;
pos, curr: longint;
found: boolean;
begin clrscr;
randomize;
assign(f, 'test.dat'); rewrite(f);
write('vvedite chislo elementov faila N=');
readln(N);
for i := 1 to N do begin
X := random(10);
write(X,' ');
write(f, X);
end;
writeln;
reset(f); pos := 0;
while not eof(f) do begin
read(f, X);
curr := filepos(f);
seek(f, 0);
found := false;
while filepos(f) < pos do begin read(f, Y);
if Y = X then found := true;
end;
if not found then begin
seek(f, pos);
write(f, X);
inc(pos);
end;
seek(f, curr);
end;
seek(f, pos); truncate(f);
reset(f);
while not eof(f) do begin
read(f, X);
write(X:3);
end;
writeln;
close(f);
assign(g,'test.dat');
reset(g,1);
sum:=0;
while not eof(g) do begin
blockread(g,buf,1);
sum:=sum + ord(buf);
end;
write('kontrolnaya summa ravna ',sum);
end.

Автор: volvo 19.12.2008 20:28

assign(g,'test.dat');       
reset(g,1); { <--- После вот такого открытия }
надо как минимум сделать buf не Integer-ом, а Char-ом (или Byte, неважно, но размером в один байт), потому что и читаешь ты тоже
blockread(g,buf,1); { <--- Один блок }

Автор: Akella 19.12.2008 20:31

почему же тогда у меня в другой проге работает и считает, да и типы по моему одинаковые...

все равно не считает, то что нужно!

Автор: volvo 19.12.2008 20:53

Цитата
все равно не считает, то что нужно!
Значит, говори, что тебе нужно... Контрольная сумма - понятие растяжимое... Можно назвать так сумму элементов, можно - CRC файла, да мало ли что еще...

Автор: Akella 19.12.2008 20:55

в этой проге мне считает, а почему в проге выше не работает я не знаю...

program  _7_14;    
uses crt;
var f : file of integer;
g : file;
i,n,a,CurrPos,LastNeg,sum,buf : integer;
begin
clrscr;
randomize;
assign(f,'myfile.dat');
rewrite(f);
write('vvedite kolichestvo sluchainih chisel n=');
read(n);
for i:=1 to n do begin
a:=random(200)-100;
write(f,a);
end;
seek(f,0);
gotoxy(1,3);
write('sluchainie chisla');
gotoxy(1,5);
while not eof(f) do begin
read(f,a);
write(a,' ');
end;
reset(f);
LastNeg := -1;
while not eof(f) do begin
read(f, a);
if a < 0 then begin
CurrPos := FilePos(f);
inc(LastNeg);
Seek(f, LastNeg);
write(f, a);
Seek(f, CurrPos);
end;
end;
Seek(f, LastNeg + 1);
Truncate(f);
reset(f);
gotoxy(1,7);
write('posle udaleniya polojitelnih chisel');
gotoxy(1,9);
while not eof(f) do begin
read(f,a);
write(a,' ');
end;
close(f);
assign(g,'myfile.dat');
reset(g,1);
sum:=0;
while not eof(g) do begin
blockread(g,buf,1);
sum:=sum + ord(buf);
end;
gotoxy(1,11);
write('kontrolnaya summa = ',sum);
end.

Автор: volvo 19.12.2008 21:02

И что это? Ты на вопрос ответь, а не подсовывай что-то что "работает"... Насчет того, работает это или нет - большой вопрос, у меня и первый твой код работает... ЧТО СЧИТАЕТ он?

Автор: Akella 19.12.2008 21:04

я затупил, и скорее всего препод тоже..... извиняюсь... mega_chok.gif